home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1993 / Internet Info CD-ROM (Walnut Creek) (1993).iso / inet / ien / ien-136 < prev    next >
Text File  |  1988-12-01  |  87KB  |  3,659 lines

  1.  
  2.  
  3.  
  4.  
  5.                       Memory Management Extensions
  6.                    to the SRI Micro Operating System
  7.                          for PDP-11/23/34/35/40
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.                                 IEN  136
  19.  
  20.                               1st MAY 1980
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.                               S.R. Wiseman
  31.                               B.H. Davies
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.                   ROYAL SIGNALS & RADAR ESTABLISHMENT
  56.            North Site, Leigh Sinton Rd., Malvern, Worcs., UK.
  57.  
  58.                                    1
  59.  
  60.  
  61.  
  62.     CONTENTS
  63.     ________
  64.  
  65. 0.    Introduction
  66.  
  67.         PART 1 - SYSTEM DESIGN
  68.  
  69. 1.    Requirement
  70.  
  71. 1.2    Overview of solution
  72.  
  73. 1.3    Use of Memory Management Facility
  74.  
  75.  
  76.         PART 2 - TARGET MACHINE ASPECTS
  77.  
  78. 2.1    Alterations to MOS
  79.     2.1.1    The Process Control Table
  80.     2.1.2    The Scheduler
  81.     2.1.3    The $CREAP Macro
  82.     2.1.4    Input and Output Routines
  83.     2.1.5    Memory Sizing
  84.     2.1.6    Protection Routines
  85.     2.1.7    System Configuration
  86.  
  87. 2.2    The EMMOS Debugger - MUD
  88.     2.2.1    A Summary of MUD Commands
  89.     2.2.2    MUD Command Syntax
  90.     2.2.3    The Relocation Mechanism
  91.     2.2.4    Addressing Modes
  92.     2.2.5    Command Specifications
  93.     2.2.6    Using MUD
  94.  
  95. 2.3    Linker and Loader Functions
  96.     2.3.1    The Linker
  97.     2.3.2    The Loader
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.                                    2
  118.  
  119.          PART 3 - HOST MACHINE ASPECTS
  120.  
  121. 3.1    Linking Using the RSX-11M Task Builder
  122.     3.1.1    Use of the Task Builder's Task Image File
  123.     3.1.2    The Format of the Task Image File
  124.     3.1.3    The Overlay Description Language
  125.     3.1.4    The EMMOS ODL File
  126.     3.1.5    Installation of the Debugger
  127.     3.1.6    Creating the Task Image File
  128.  
  129. 3.2    The EMMOS RSX Task Image Loader
  130.     3.2.1    Inputs and Outputs
  131.     3.2.2    The Console Load Map
  132.     3.2.3    The Configuration Table
  133.     3.2.4    The Overlay Description Table
  134.     3.2.5    The Process Description Table
  135.     3.2.6    The Load Map
  136.     3.2.7    The Physical Memory Allocation Algorithm
  137.     3.2.8    The Logical Operation of the Loader
  138.     3.2.9    Error Messages
  139.     3.2.10    Tracing
  140.     3.2.11    Changing the System
  141.  
  142. 3.3    Process Creation
  143.  
  144.  
  145.  
  146.  
  147.  
  148. Appendix A:    Pitfalls and How to Avoid Them
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.                                    3
  177.  
  178.  
  179.  
  180. 0.    Introduction
  181. ____________________
  182.  
  183.      This  document describes the requirement, design and implementation
  184. of  memory  management  extensions  to  the Stanford Research Insitute's
  185. Micro  Operating  System (MOS) for PDP-11 minicomputers. The document is
  186. divided  into three parts. Part 1 covers the rationale behind the way in
  187. which  the memory management facility of the PDP-11 is used. The results
  188. of  the  work  fall  naturally  into Parts 2 and 3. Part 2 describes the
  189. modifications  to  MOS  itself and the debugger which are independent of
  190. the  operating  system of the host machine on which the target system is
  191. generated.  Part  3  describes the Linking and Loading modules which are
  192. dependent on the operating system of the host machine. The host machines
  193. used  at  RSRE are PDP -11/34 and 40s running RSX-11M v3.2. Also we have
  194. provision  in  our  standard  MOS  for writing processes in a high level
  195. language, CORAL 66, which requires the use of an auxiliary stack pointed
  196. to by R0. This facility may be excluded from the extended MOS by the use
  197. of a configuration switch.
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.                                    4
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.                 PART ONE
  250.                 ________
  251.  
  252.                  SYSTEM DESIGN
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.                                    5
  295.  
  296. 1.1    Requirement
  297. ___________________
  298.  
  299.      For  a  number of planned real-time software projects the 28k words
  300. of  code  and  data  space  accessible  without memory management in the
  301. PDP-11  is  inadequate.  Therefore the question arises is it possible to
  302. use  the  memory  management  registers to provide more code and/or data
  303. space  up  to  124k words, with minimal overheads in the form of context
  304. switching and with no modifications to presently written processes?
  305.  
  306.  
  307. 1.2    Overview of Solution
  308. ____________________________
  309.  
  310.  
  311.      The  reason  for  the  provision  of  a two state memory management
  312. system  in  the  PDP-11s is not only to allow access to memory above 28k
  313. words  but  also,  by  the  use  of  kernel  and  user modes, to provide
  314. protection between processes and the core resident part of the operating
  315. system. This usually means that the I/O page is non-resident when a user
  316. process  is  running  and  that I/O is handled in kernel mode. Thus in a
  317. real-time  system  there  may  be  unacceptable  overheads  due  to  the
  318. considerable  amount  of  context  switching involved in this protection
  319. mechanism.  However  if one is willing to dispense with interprocess and
  320. operating system protection a simple and elegant solution which produces
  321. no detectable overheads is possible.
  322.  
  323.      The  basic  concept  of  the  solution  is  that while a process is
  324. running  there  is  no need to have in scope any other process so that a
  325. snapshot  of  the  32k  virtual memory at any one time will look like an
  326. ordinary   MOS  system  configured  for  one  process.  The  only  extra
  327. executable  code involved is in the scheduler for paging out the process
  328. that  has  just finished running and paging in the process that is about
  329. to  be  run.  The I/O page, operating system, handlers and common buffer
  330. area  are  always resident otherwise access to these entities would have
  331. to  be  mediated  by the operating system so that they could be paged in
  332. with  consequent  increase  in overheads. A typical MOS process runs for
  333. something like 1 millisecond and the additional paging overhead is 4 MOV
  334. instructions  taking  about  20  micro  seconds,  a 2% overhead. A major
  335. change  in  the  MOS  layout  occurs  in  the positioning of the stacks.
  336. Because  we  want the permanently resident part of MOS to be as small as
  337. possible  and  never  greater than 8k words the stacks have been removed
  338. from  the  Process  Control  Tables  and are paged in and out with their
  339. processes.
  340.  
  341.  
  342. 1.3    Use of the Memory Mangement Facility
  343. ____________________________________________
  344.  
  345.      At  any  one  time  only the running process will reside in virtual
  346. memory,  the  others  will  be  suspended  and  so  have  no  need to be
  347. accessible.  Permanently  resident  in virtual memory will be the vector
  348. area,  global  buffer area, operating system including all handlers, and
  349. the  I/O  page.  Because the maximum size of a page is 4K words and it's
  350. position  is  fixed  in virtual memory, the allocation of these pages is
  351. somewhat  restricted.  However  a trade-off between global buffer space,
  352.  
  353.                                    6
  354.  
  355. operating  system size and process space is possible to some extent, and
  356. the following configurable options are catered for:-
  357.  
  358.  
  359. Options where code and stack space of any process does not exceed 4k words:-
  360.  
  361.  
  362.     Option 1
  363.     ________
  364.  
  365.     20k words of buffer space
  366.     <4k of operating system and handlers
  367.  
  368.  
  369.             |-----------------------| 32k
  370.         7    |    I/O        |
  371.             |-----------------------| 28k
  372.         6    |Running process & stack|
  373.             |-----------------------| 24k
  374.         5    | Operating System EMMOS|
  375.             |-----------------------| 20k
  376.         4    | Global Buffers        |
  377.             |-                     -| 16k
  378.         3    |            |
  379.             |-                     -| 12k
  380.         2    |            |
  381.             |-                     -|  8k
  382.         1    |            |
  383.             |-                     -|  4k
  384.         0    |            |
  385.           page    |-----------------------|  0k
  386.  
  387.     Option 2
  388.     ________
  389.  
  390.     16k words of buffers
  391.     <8k operating system and handlers
  392.             |-----------------------| 32k
  393.         7    |    I/O        |
  394.             |-----------------------| 28k
  395.         6    |Running process & stack|
  396.             |-----------------------| 24k
  397.         5    | Operating System EMMOS|
  398.             |-                     -| 20k
  399.         4    |            |
  400.             |-----------------------| 16k
  401.         3    | Global buffers        |
  402.             |-                     -| 12k
  403.         2    |            |
  404.             |-                     -|  8k
  405.         1    |            |
  406.             |-                     -|  4k
  407.         0    |            |
  408.           page    |-----------------------|  0k
  409.  
  410.  
  411.  
  412.                                    7
  413.  
  414.  
  415. Options where code and stack space of any process does not exceed 8K words:-
  416.  
  417.     Option 3
  418.     ________
  419.  
  420.     16k words of buffer space
  421.     < 4k words of operating system and handlers
  422.  
  423.             |-----------------------| 32k
  424.         7    |    I/O        |
  425.             |-----------------------| 28k
  426.         6    |Running process & stack|
  427.             |-                     -| 24k
  428.         5    |            |
  429.             |-----------------------| 20k
  430.         4    | Operating System EMMOS|
  431.             |-----------------------| 16k
  432.         3    |  Global Buffers       |
  433.             |-                     -| 12k
  434.         2    |            |
  435.             |-                     -|  8k
  436.         1    |            |
  437.             |-                     -|  4k
  438.         0    |            |
  439.           page    |-----------------------|  0k
  440.  
  441.     Option 4
  442.     ________
  443.  
  444.     12k words of buffers
  445.     <8k words for operating system and handlers
  446.  
  447.             |-----------------------| 32k
  448.         7    |    I/O        |
  449.             |-----------------------| 28k
  450.         6    |Running process & stack|
  451.             |-                     -| 24k
  452.         5    |            |
  453.             |-----------------------| 20k
  454.         4    | Operating System EMMOS|
  455.             |-                     -| 16k
  456.         3    |            |
  457.             |-----------------------| 12k
  458.         2    | Global Buffers        |
  459.             |-                     -|  8k
  460.         1    |            |
  461.             |-                     -|  4k
  462.         0    |            |
  463.           page    |-----------------------|  0k
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.                                    8
  472.  
  473.      Only  kernel  mode  is  used  by  EMMOS, even user processes run in
  474. kernel mode because no attempt has been made to produce a secure system.
  475. However  with  options  3  and  4  the process space and stack space are
  476. allocated  separate  pages  wherever  possible.  Thus  the debugger or a
  477. procedure  call  may be used to write-protect the code space if desired.
  478. Holes  appear in virtual memory from the end of the code or stack to the
  479. end of the 4k boundary ensuring that a system stack cannot underflow and
  480. the  running  process  cannot  access  another  process' code or stack .
  481. However,  a  process  can  damage  another  process  indirectly  by, for
  482. example, supplying a pointer to data on its stack to another process.
  483.  
  484.      Because  the  debugger  is  bigger  than 4k, options 1 and 2 do not
  485. allow  use  of  the  debugger.  This  is not a serious drawback as it is
  486. envisaged  that  debugging could take place with options 3 or 4 and that
  487. options  1  or  2  could then be used to give another 4k words of buffer
  488. space.
  489.  
  490.      Using  EMMOS  requires a stricter discipline when writing processes
  491. than  was  required  with  MOS.  Strictly speaking the code of a process
  492. should  not  contain  any private data space. If a process wants private
  493. data  space  it  should use its stack. Any data space shich is shared by
  494. two  or  more  processes should be obtained , via MOSMEM calls, from the
  495. global  buffer  area. Exceptionally a single incarnation of an assembler
  496. process  could  reserve  space  after  its code for local tables but any
  497. attempt  by another process to access this area will result in disaster!
  498. All high level language processes should be written as closed procedures
  499. with private data area on their stacks.
  500.  
  501.      Shared  Library  procedures  must either be replicated so that they
  502. are paged in with each process that requires to use them or they must be
  503. linked  with  the  EMMOS  operating  system so that they are permanently
  504. resident
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.                                    9
  531.  
  532.     A typical example of real and virtual memory allocations for
  533. an EMMOS system are shown  below:-
  534.                  128k    |-----------------------|
  535.                     | I/O addresses         |
  536.                  124k    |-----------------------|
  537.  
  538.                     |            |
  539.  
  540.                     |            |
  541.                     |            |
  542.                     |-----------------------|
  543.                     | stack (proc3)         |
  544.                     |-----------------------|
  545.                      | stack (proc2)         |
  546.     |-----------------------| 32k    |_______________________|
  547.    7    |    I/O        |    | Codebody2 (proc 2&3)  |
  548.     |-----------------------| 28k    |_______________________|
  549.    6    |Running process & stack|    | stack (proc1)         |
  550.     |-                     -| 24k    |_______________________|
  551.    5    |            |    | Codebody1 (proc1)     |    
  552.     |-----------------------| 20k    |-----------------------|
  553.    4    | Operating System EMMOS|    | Operating System EMMOS| 
  554.     |-                     -| 16k    |-               -|
  555.    3    |            |    |            |
  556.     |-----------------------| 12k    |-----------------------|
  557.    2    | Global Buffers        |    | GLOBAL buffers        |
  558.     |-                     -|  8k    |-                     -|
  559.    1    |            |    |            |
  560.     |-                     -|  4k    |-                     -|
  561.    0    |            |    |            |
  562.     |-----------------------|  0k    |-----------------------|
  563. Page        Virtual Memory            Physical Memory
  564.  
  565.  
  566.  
  567.  
  568.      The  linker/loader  system  used  with  EMMOS  should be reasonably
  569. intelligent!  It  is  it's  job to reserve physical memory in accordance
  570. with  the  stack  size requested for each process. In particular it must
  571. evaluate  the  total memory requirements of a process that has more than
  572. one incarnation and determine whether or not some or all of the code has
  573. to  be replicated.This may arise when the stacks of all the incarnations
  574. of  a  process  plus  the  code will not fit into the paging window. The
  575. linker/loader is also responsible for outputting error messages when the
  576. process  and  stack  requirements cannot be satisfied by that particular
  577. configuration of EMMOS.
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.                                    10
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.                 PART TWO
  601.                 ________
  602.  
  603.                  TARGET MACHINE ASPECTS
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.                                    11
  649.  
  650.     2.1     Alterations to MOS
  651.     ___________________________
  652.  
  653.      Perhaps  the most vital alteration is that made to the scheduler. A
  654. context  swap  now  involves  saving  the  suspended process' window and
  655. restoring  the  new  process'  window. This however, only involves about
  656. four move instructions extra, for a typical configuration ( 8K processes
  657. ).
  658.  
  659.      The  major  alteration is, however, to the Process Control Tables (
  660. PCTs ) and consequently to the PCT initializer. In particular the stacks
  661. for  a process no longer reside here, hence a process' PCT is relatively
  662. small.  Extra  fields  in  the  PCTs  give  the memory management window
  663. necessary  to 'page-in' the process and the ends of the system and CORAL
  664. stacks.  The  PCT  initializer  now  has  to  cope with setting up these
  665. fields,  which  it  does  by  consulting  the  load map, supplied by the
  666. linker/loader.
  667.  
  668.      Additions have also been made to the $CREAP macro. The sizes of the
  669. system and CORAL stacks are given to the $CREAP which in turn passes the
  670. information to the linker/loader ( depending on the method used ).
  671.  
  672.      It  has  also  been  necessary  to  offer  modified synchronous I/O
  673. routines  'SOUT' and 'SIN'. The original versions can be used if the I/O
  674. is  performed  on  buffers  from  the  permanently resident buffer pool,
  675. however  they  will  not  work if the I/O buffer is taken from the local
  676. code or data space. This is because the local area may be paged-out when
  677. the  interrupt  routine  tries  to get the next character, causing it to
  678. pick  up  rubbish  or trap out. The new versions will copy the local I/O
  679. buffer  into  a  global  buffer before initiating the I/O, thus ensuring
  680. that  it  is  always paged-in. This is likely to be the main overhead of
  681. the system.
  682.  
  683.      Finally,  the  memory  sizing  performed  in  MOSMEM  is  no longer
  684. required.  This  is  because  the  position of the global buffer pool is
  685. fixed by the page allocation scheme.
  686.  
  687.  
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.                                    12
  708.  
  709.     2.1.1 The Process Control Table
  710.  
  711. The following fields have been added to the PCT:
  712.  
  713.     pct_mmr : ARRAY [ first_page..last_page ] OF window_type;
  714.     pct_r0e, pct_r6e : virtual_byte_addresses;
  715. where
  716.     TYPE window_type = RECORD par, pdr : INTEGER  END;
  717.     TYPE virtual_byte_addresses = 0..#177777;
  718.  
  719. The following field has been removed from the PCT:
  720.  
  721.     pct_stk : ARRAY [ 1..stk_len ] OF BYTES
  722.  
  723.      pct_mmr is an array containing the window required to 'page-in' the
  724. process.  The  bounds  are  not 0..7 because it is known that most pages
  725. remain  constant,  only  pages first_page to last_page are changed since
  726. this  is  the  amount  of  virtual  memory  allocated to a process. Each
  727. element  of  the  array is four bytes long and contains the page address
  728. register  (  par  ) and page descriptor register ( pdr ) values for that
  729. page.
  730.  
  731.      pct_r0e  and pct_r6e contain the virtual byte addresses of the ends
  732. (  smallest  numbered  address  )  of the R0 ( CORAL ) and R6 ( system )
  733. stacks. These values are used to detect stack overflow.
  734.  
  735.      Since  the stacks no longer reside in the PCT the field pct_stk has
  736. been removed.
  737.  
  738.      The  new  fields  in  the PCT are set up directly from the Load Map
  739. produced by the linker/loader.
  740.  
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.                                    13
  767.  
  768.     2.1.2 The Scheduler
  769.  
  770.      A  context  swap  now  involves  saving  and  restoring  the memory
  771. mapping,  as  well as the general register values. We can actually avoid
  772. saving  the  mapping  when  a  process  is suspended because normally it
  773. remains  constant.  The protection on a page is the only thing likely to
  774. change and if this is done using the supplied routines then we can still
  775. avoid doing the saving.
  776.  
  777.      When  the  process  is  made  runnable  it  is  first 'paged-in' by
  778. restoring it's memory mapping. To ensure that the stack pointer and it's
  779. stack are restored together, interrupts are disabled earlier than in the
  780. old version. If an interrupt is allowed to occur between 'paging-in' the
  781. stack  and  restoring  the  stack  pointer  then disaster will obviously
  782. follow.
  783.  
  784.      Stack  overflow, on both the R0 ( CORAL ) and R6 ( system ) stacks,
  785. is checked for when the process is suspended. The ends of the stacks are
  786. marked  with  overflow detect words, the address of which is held in the
  787. PCT.  It is a simple matter to check if these words are still intact. If
  788. the  system  has  no CORAL processes or library routines then the checks
  789. made  on  the  R0  stack can be omitted by setting a switch in the EMMOS
  790. configuration file.
  791.  
  792.     2.1.3 The $CREAP Macro
  793.  
  794.      This  macro  initializes  parts of the PCT, the rest is done at run
  795. time.  Two extra parameters are now required, which specify the size, in
  796. words,  of the R0 ( CORAL ) and R6 ( system ) stacks. To avoid confusion
  797. the parameters should be called by name, the default size is zero words:
  798.  
  799. eg:    $CREAP    G802,<UX25  >,,DV.IMP+0,DV.IMP+1,R0SIZE=200,R6SIZE=20
  800.     $CREAP    G802,<UX25  >,,DV.IMP+2,DV.IMP+3,R6SIZE=30,R0SIZE=350
  801.  
  802.      The  macro  converts the size into memory blocks ( 40 octal words )
  803. and  places  the information, along with the process id and name, in the
  804. .PSECT  LDRCON.  This  information is used by the linker/loader in a way
  805. that depends on the methods being used. Note that different incarnations
  806. of  the  same  process  can have different sizes of stacks. In the above
  807. example ( all numbers are octal ) the first process would have
  808.  
  809.     ceiling( 200/40 ) =  4 memory blocks = 200 words for R0
  810.     ceiling(  20/40 ) =  1 memory block  =  40 words for R6
  811. and the second process would have
  812.     ceiling( 350/40 ) = 10 memory blocks = 400 words for R0
  813.     ceiling(  30/40 ) =  1 memory block  =  40 words for R6
  814.  
  815.      Note:  "ceiling(  r )" is a function that rounds up real numbers to
  816. the next largest integer.
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.  
  825.                                    14
  826.  
  827.     2.1.4 Input and Output Routines
  828.  
  829.      The synchronous I/O routines, SIN and SOUT, have to be modified for
  830. use  with  EMMOS.  The  user  interface  is unchanged, but the method of
  831. operation  is slightly different. SOUT now grabs a global buffer, copies
  832. the  string  into it from the user's buffer and then performs the SIO on
  833. the  global buffer, to output the characters. SIN grabs a global buffer,
  834. calls SIO to fill it and then copies the string into the user's buffer.
  835.  
  836.      This  is  necessary  because  if  the string to be output is in the
  837. process' local area, it will be 'paged-out' with the process. SIO uses a
  838. pointer to the string ( a virtual address ) to get the characters, so if
  839. it  does this when the initiating process is 'paged-out', it will either
  840. pick up rubbish or cause a memory management error. Similarly for SIN.
  841.  
  842.      The  copying would not be required for a string already in a global
  843. buffer,  because  the  buffer  will  always be 'paged-in', regardless of
  844. which process is running. In this case the MOS versions could be renamed
  845. and used to avoid a loss of efficiency.
  846.  
  847.      The  same  problems  apply  to  the  asynchronous I/O routine, SIO.
  848. However,  any  copying  from local data space to a global buffer that is
  849. needed,  is  left  up to the user. Checks have been included in the code
  850. that  ensure  both  the  IORB and the data area are in the global buffer
  851. pool  or  the  resident  EMMOS  code.  These checks can be omitted for a
  852. program  known  to  work  by setting a switch in the EMMOS configuration
  853. file.
  854.  
  855.     2.1.5 Memory Sizing
  856.  
  857.      This  is  now not carried out. The limits of the global buffer area
  858. are  assumed  to  be  the  ends of the pages allocated to buffers ( less
  859. space  for the vectors if this includes page 0 ). It is assumed that the
  860. hardware has been configured in a sensible manner.
  861.  
  862.  
  863.  
  864.  
  865.  
  866.  
  867.  
  868.  
  869.  
  870.  
  871.  
  872.  
  873.  
  874.  
  875.  
  876.  
  877.  
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.                                    15
  885.  
  886.     2.1.6 Protection Routines
  887.  
  888.      Two  routines are supplied, one to inspect the access control field
  889. (  ACF  )  of  a  page,  the  other  to change the ACF. Under the memory
  890. management system each page can be either
  891.  
  892.     1.    non-resident    -all attempts at access will cause
  893.                  a trap
  894.     2.    read-only    -attempts to write into a location
  895.                  in the page will cause a trap
  896.     3.    (unused)    -same as non-resident
  897.     4.    read/write    -neither reads nor writes are trapped
  898.  
  899.      The  two routines will only work for one of the process pages. They
  900. both  return an integer result. This equals 'true' if the page specified
  901. is  a process page, else it equals 'false' and the ACF is not changed or
  902. inspected.  The  pre-defined constants, 'non resident', 'read only', 'un
  903. used' and 'read write', should be used to specify and compare the ACFs.
  904.  
  905. INTEGER PROCEDURE change page protection ( VALUE INTEGER page, access );
  906.  
  907.      If  the  page specified is a process page then the ACF of that page
  908. is  changed  to  the  given  access.  The  copy of the memory management
  909. registers held in the PCT table for this process, is also updated.
  910.  
  911. INTEGER PROCEDURE current protection ( VALUE INTEGER page;
  912.                        LOCATION INTEGER pct, pdr );
  913.  
  914.      If the page specified is a process page then pct and pdr are set to
  915. the  values of the ACF field of the memory management registers for that
  916. page,  taken  from  the  PCT  window  area  and  active  page  registers
  917. respectively.  The  two  different  versions are supplied in case one of
  918. them has been corrupted. Both should always be the same.
  919.  
  920.  
  921.     CORAL Constant Values
  922.  
  923.     true        1
  924.     false        0
  925.     non resident    0
  926.     read only    2
  927.     un used        4
  928.     read write    6
  929.  
  930.  
  931.  
  932.  
  933.  
  934.  
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943.                                    16
  944.  
  945. cont.
  946.  
  947.      The  assembler  versions of these routines are completly re-entrant
  948. and run to completion, so it is possible to have one copy of the code in
  949. the  resident  part of the system which is shared between all processes.
  950. The  routine  to  change  the  page  protection is called $CHAPP and the
  951. routine  to  inspect  the current protection is called $CURPP, they have
  952. the same effect as the CORAL versions but are called as follows:
  953.  
  954.  
  955.  
  956. Change Page Protection :
  957.     called by JSR    PC,$CHAPP
  958.     with    R2 = number of the page to be changed
  959.         R3 = the new access of that page
  960.     returns with
  961.         R1 = TRUE or FALSE
  962.         R0 and R2...R6 unchanged
  963.  
  964. Inspect Current Page Protection :
  965.     called by JSR    PC,$CURPP
  966.     with    R2 = number of page to be examined
  967.     returns with
  968.         R1 = TRUE or FALSE
  969.         R3 = value from PCT
  970.         R4 = value from active PDR
  971.         R0, R5 and R6 unchanged
  972.  
  973.  
  974. Assembler Constant Values
  975.  
  976.     TRUE    1
  977.     FALSE    0
  978.     NONRES    0
  979.     READON     2
  980.     UNUSED    4
  981.     RWRITE    6
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.  
  998.  
  999.  
  1000.  
  1001.  
  1002.                                    17
  1003.  
  1004.     2.1.7 System Configuration
  1005.  
  1006.      The  page  allocation  scheme, operating system options and various
  1007. buffer addresses, are specified in the configuration file, EMMSYS.SML .
  1008.  
  1009.     2.1.7i The Page Allocation Scheme
  1010.  
  1011.      The virtual memory is divided up into 8 pages of 4K words, numbered
  1012. 0..7.  Page  7 is always allocated for the I/O page, the remaining seven
  1013. are  split  between  the  global  buffers,  the operating system and the
  1014. running  process  (  including  it's  stacks  ).  The order is critical,
  1015. buffers  should  be  at  the low numbered end, then the system, then the
  1016. process and finally the I/O page. The exact split is given by specifying
  1017. the first and last page used by each part.
  1018.  
  1019. eg    buffers    0 - 3    emmos    4 - 5    process    6 - 6
  1020. or    buffers 0 - 2    emmos    3 - 4    process    5 - 6
  1021.  
  1022.      When  decreasing the space allocated to the global buffers, be sure
  1023. that  the  workspace  buffers  ( see 2.1.7iii ) are still located before
  1024. EMMOS,  otherwise  EMMOS may be loaded on top of one of them before it's
  1025. finished   with.   Note:  different  linking/loading  schemes  may  lend
  1026. themselves  to  a  different ordering of buffers, system and process, in
  1027. which  case  minor  alterations to the PCT initializer may be necessary.
  1028. The I/O page must always be page 7.
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.                                    18
  1062.  
  1063.     2.1.7ii Operating System Options
  1064.  
  1065.  
  1066. EMMOS:        EMMOS/MOS selection switch
  1067.     = 0    for EMMOS
  1068.     = 1    for MOS ( SAVMAP  and SET250 have no meaning )
  1069.  
  1070. SAVMAP:        save mapping when process suspended switch
  1071.     = 0    when a process is suspended the window is saved as part
  1072.         of the process' volatile environment. This allows a 
  1073.         process to change the window dynamically ( eg the
  1074.         protection ). Note, only that part of the window for the
  1075.         pages allocated to processes is saved and restored, so
  1076.         changing other pages will affect all processes.
  1077.     = 1    the window is not saved each time the process is 
  1078.         suspended. The original value is reloaded when the
  1079.         process is run again, erasing any changes made.
  1080.  
  1081.     It is recommended that SAVMAP = 1 and the supplied protection
  1082.     routines are used to change the page allocation, with the other
  1083.     fields left well alone.
  1084.  
  1085. SET250:        memory management error trap initialization on/off
  1086.     = 0    when the system is initialized the trap is set to a local
  1087.         handler.
  1088.     = 1    the trap is left untouched, this option should only be
  1089.         used when the debugger is used ( MUD will set up it's
  1090.         own handler ).
  1091.  
  1092. COPYIO:        sin/sout version selection switch
  1093.     = 0 ( OR EMMOS = 0 )
  1094.         use the versions of sin and sout that copy to/from a
  1095.         global buffer before initiating the I/O.
  1096.     = 1 ( AND EMMOS = 1 )
  1097.         the MOS versions will be used
  1098.  
  1099. NOCORL:    CORAL process indicator
  1100.     = 0    no processes are written in CORAL, or use CORAL libraries,
  1101.         so the R0 stack is not checked for overflow each time a
  1102.         process is suspended. The stack is still set up as
  1103.         usual. The R6 stack is still checked.
  1104.     = 1    There is a process using CORAL, so the R0 stack will
  1105.         be used. Both stacks are checked for overflow each
  1106.         time the process is suspended.
  1107.  
  1108. CHKSIO:    SIO buffer address checking on/off
  1109.     =0    Each time SIO is called the IORB and the data addresses
  1110.         are checked to ensure that they are in the global buffer
  1111.         pool or the resident EMMOS code. An attempt to use a 
  1112.         local iorb or data area will cause a BUGHLT.
  1113.     =1    No checks are performed. The use of a local IORB or data
  1114.         area is likely to cause the system to crash.
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.                                    19
  1121.  
  1122.     2.1.7iii Workspace Buffer Addresses
  1123.  
  1124.      The  linker/loader and system initializer must agree on the postion
  1125. of  the  load  map.  It's  address  is  given  by  MAPADD  in the system
  1126. configuration  file. The linker/loader is given this information in some
  1127. implementation dependant way.
  1128.  
  1129.      Note  that  in  the RSX linker/loader system, the area specified by
  1130. MAPADD  is  also  used  by the loader for other workspace buffers during
  1131. load  time,  because of this MAPADD must specify an area of store, lying
  1132. between  the  end of the loader and the beginning of where EMMOS will be
  1133. loaded, of about
  1134.  
  1135.     25 * max_number_of_processes ( decimal ) words long
  1136.  
  1137.      The   loader   ends   around  032000,  without  removing  redundant
  1138. libraries, so even for a max number of 30 processes ( 25 * 30 decimal is
  1139. about  1400  octal  ), giving MAPADD = 32000 would mean the tables would
  1140. end  way  below  040000. This allows us to load a system with only 8K of
  1141. buffers.
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.                                    20
  1180.  
  1181.     2.2    The EMMOS Debuggger  - MUD
  1182.     __________________________________
  1183.  
  1184.      MUD (Marvellous Universal Debugger) is split into two parts, RESMUD
  1185. and  MUD  proper.  RESMUD is a small program written in MACRO-11 that is
  1186. permanently resident in virtual memory. It acts as the interface between
  1187. the  operating  system and the debugger, MUD, which is only brought into
  1188. virtual memory when it is needed.
  1189.  
  1190.      MUD  is  loaded by the loader in the same way as any other overlay.
  1191. Normally  ,  however, overlays that are not $CREAPed do not have entries
  1192. in  the  load  map,  but  the  loader  creates  a  special entry for the
  1193. debugger.  RESMUD uses this entry to find out where MUD has been loaded,
  1194. and  transfers  control  to it. For this reason RESMUD must be the first
  1195. module loaded, even before MOSPM, if the debugger is to be used.
  1196.  
  1197.      If  RESMUD  is not included in the system, then MUD will be ignored
  1198. if  it  is  itself included, and the debugger cannot be used. EMMOS will
  1199. ignore MUD, unless a process is foolishly creaped with the name MUDSYS!
  1200.  
  1201.      The  debugger is able to reference the whole of the 18 bit physical
  1202. store   without  the  user  knowingly  changing  the  memory  management
  1203. registers.
  1204.  
  1205.  
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.                                    21
  1239.  
  1240.     2.2.1 A Summary of MUD Commands
  1241.  
  1242.      The name of a command is one or two letters long, in upper or lower
  1243. case, as follows:
  1244.  
  1245. Print Commands:
  1246.  
  1247.     pb    print breakpoint locations
  1248.                 ( see breakpoint commands )
  1249.     pr    print the value of a relocation register
  1250.                 ( see relocation commands )
  1251.  
  1252. Spy Commands:
  1253.  
  1254.     s    spy on store
  1255.     sr    spy on the registers
  1256.     sw    spy on the memory management window
  1257.  
  1258. Breakpoint Commands:
  1259.  
  1260.     b    set a breakpoint
  1261.     k    kill a breakpoint
  1262.     pb    print breakpoint locations
  1263.                 ( see print commands )
  1264.  
  1265. Enter User Program Commands:
  1266.  
  1267.     g    go to a specific address
  1268.     gs    go to a specific address single stepping
  1269.     c    continue from a breakpoint
  1270.     cs    continue from a breakpoint single stepping
  1271.  
  1272. Relocation Commands:
  1273.  
  1274.     r    set a relocation register
  1275.     pr    print the value of a relocation register
  1276.                 ( see print commands )
  1277.  
  1278. Exit Command
  1279.  
  1280.     x    leaves MUD and halts
  1281.  
  1282. Special Commands
  1283.  
  1284.     i    change I/O channel
  1285.     e    evaluate an arithmetic expression
  1286.     f    find a memory location containing a given value
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293.  
  1294.  
  1295.  
  1296.  
  1297.                                    22
  1298.  
  1299.     2.2.2 MUD Command Syntax
  1300.  
  1301.      The  syntax  is  fairly  simple  and  is  quite free with spaces. A
  1302. command consists of the command name, one or two letters( upper or lower
  1303. case ), optionally followed by one or two operands.
  1304.  
  1305.     <name>
  1306.     <name> <op1>
  1307.     <name> <op1> <op2>
  1308.  
  1309.      The two operands and the name may be seperated by commas or spaces.
  1310. The  operands specify 18 bit addresses or numbers in octal. Their syntax
  1311. is:
  1312.  
  1313.     <operand> ::= <repeat symbol>
  1314.           or= <number> <relocation> <mode>
  1315.  
  1316.     <repeat symbol>    ::=  *
  1317.  
  1318.     <number>  ::= <18 bit octal number>
  1319.           or= null
  1320.  
  1321.     <relocation> ::=  .  <relocation register>
  1322.              or= null
  1323.  
  1324.     <relocation register> ::= <octal digit>
  1325.                           or= null
  1326.  
  1327.     <mode> ::= V
  1328.            or= P
  1329.            or= null
  1330.  
  1331.      If  the  octal  digit is ommitted, it is assumed to be zero. If the
  1332. relocation  dot  is  not  present,  then the operand is assumed to be an
  1333. absolute  physical  address.  If  the  octal  digit  is missed out, then
  1334. relocation  register  one  is  assumed. Hence the following examples all
  1335. mean the same:
  1336.  
  1337.     s100.,150.
  1338.     s100.1  150.
  1339.     s 100.   ,   150.1
  1340.     s 100.1   150.1
  1341.  
  1342.  
  1343.  
  1344.  
  1345.  
  1346.  
  1347.  
  1348.  
  1349.  
  1350.  
  1351.  
  1352.  
  1353.  
  1354.  
  1355.  
  1356.                                    23
  1357.  
  1358.     2.2.3 The Relocation Mechanism
  1359.  
  1360.      There  are  seven relocation registers supplied ( r1..7 ) which can
  1361. be  used  to  modify  an address in a command. Values are put into these
  1362. registers  by  the 'r' command (qv). To specify that an address is to be
  1363. relocated  it is followed by a dot and perhaps a digit. The digit is the
  1364. name  of  the relocation register to be used and is one by default. When
  1365. relocation  is  specified,  the  contents of the relocation register are
  1366. added to the address giving the actual address used. For example:
  1367.  
  1368.     r2,100    - sets relocation register 2 to 100
  1369.     s20.2    - spys on location 20+100=120
  1370.     r350    - sets relocation register 1 to 350
  1371.     s30.    - spys on location 30+350=400
  1372.  
  1373.      Many  commands  allow  an  asterisk  to be used as an operand, this
  1374. usually means 'all' in some way, for example:
  1375.  
  1376.     k100    - kill the breakpoint at location 100
  1377.     k *    - kill all breakpoints
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  
  1402.  
  1403.  
  1404.  
  1405.  
  1406.  
  1407.  
  1408.  
  1409.  
  1410.  
  1411.  
  1412.  
  1413.  
  1414.  
  1415.                                    24
  1416.  
  1417.     2.2.4 Addressing Modes
  1418.  
  1419.      An  operand  can  refer  to  a  virtual  location  by following the
  1420. relocation  indicator  by  a  'V' ( the default mode is 'P', so normally
  1421. addresses  are  physical  ). The corresponding physcial location will be
  1422. computed using the user's window. Page lengths are ignored.
  1423.  
  1424.      For  example,  if  the  base  address of page 5 ( virtual addresses
  1425. 120000-137777  )  is  120100  and relocation register 2 contains 120000,
  1426. then the following are equivalent:
  1427.  
  1428.     s120110   - physical address by default
  1429.     s120110p  - physical address specified
  1430.     s120010v  - pa = 010 + base(5) = 120110
  1431.     s110.2    - pa = 110 + 120000  = 120110
  1432.     s110.2p   -   . . . . physical specified
  1433.     s10.2v    - va = 10 + 120000 = 120010
  1434.               - pa = 010 + base(5) = 120110
  1435.  
  1436.  
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457.  
  1458.  
  1459.  
  1460.  
  1461.  
  1462.  
  1463.  
  1464.  
  1465.  
  1466.  
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.  
  1473.  
  1474.                                    25
  1475.  
  1476.     2.2.5 Command Specification
  1477.  
  1478.  
  1479. pb    print breakpoint locations
  1480.  
  1481.     pb    prints out a list of all the breakpoints
  1482.         that are set, showing their location as an
  1483.         absolute address and as an offset +
  1484.         relocation.
  1485.  
  1486. pr    print relocation registers
  1487.  
  1488.     pr    print out the value of relocation register 1
  1489.     pr 'd'    print out the value of relocation register 'd'
  1490.     pr *    print out the value of all the relocation
  1491.         registers.
  1492.  
  1493. r    set a relocation register
  1494.  
  1495.     r 'n'    set relocation register 1 to 'n'
  1496.     r 'd' 'n'    set relocation register 'd' to 'n'
  1497.     r * 'n'    set all relocation registers to 'n'
  1498.     r *    note that 'n' is zero by default so that
  1499.         r* will set all relocation registers to 
  1500.         zero. Initially all are zero anyway.
  1501.  
  1502. x    exit
  1503.  
  1504.     x    leaves MUD and halts. This instruction would only
  1505.         be used when running under a monitor operating system.
  1506.  
  1507.  
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.  
  1531.  
  1532.  
  1533.                                    26
  1534.  
  1535. cont.
  1536.  
  1537.  
  1538. s    spy on store
  1539.  
  1540.     s 'l'    spy on the store starting at location 'l'.
  1541.         The address is displayed followed by the
  1542.         contents. The contents can be changed by
  1543.         typing a number followed by <return>, in
  1544.         which case the new value will be displayed.
  1545.         To advance to the next location just type
  1546.         space, to retreat to the previous location
  1547.         type tab. To finish the spy type <return>.
  1548.         Note that typing <return> with no number
  1549.         does not change the value in store.
  1550.  
  1551.         eg
  1552.         mud> r100
  1553.         mud> s20.
  1554.         000120> 123456  23
  1555.         000120> 000023   000122> 077177
  1556.         mud>
  1557.  
  1558.         this leaves location 122 unchanged, but puts
  1559.         23 into location 120.
  1560.  
  1561.     s 'l1' 'l2'
  1562.         spys on locations 'l1' to 'l2', but does
  1563.         not allow you to change any values.
  1564.         Effectively this is just a display or dump
  1565.         command. 'l1' should be less than or equal
  1566.         to 'l2' or nothing will happen. To stop
  1567.         the printing hit <escape>. This is handy if
  1568.         you specify an enormous amount of printing
  1569.         by mistake.
  1570.  
  1571. sr    spy on registers
  1572.  
  1573.     sr    spys starting at register 0
  1574.     sr 'd'    spys starting at register 'd'
  1575.         This is similar to spy on store, but you can
  1576.         only progress forward one register at a
  1577.         time, by typing <space>. After reaching
  1578.         register 7, the program counter, you get to
  1579.         look at the psw. The only way to spy on the
  1580.         psw is to first spy on register 7. If you
  1581.         space forward from the psw you get back to
  1582.         register 0, to get out of the spy type
  1583.         <return>.
  1584.  
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.  
  1591.  
  1592.                                    27
  1593.  
  1594. cont.
  1595.  
  1596.  
  1597. sw    spy on the window
  1598.  
  1599.     sw    spy on the memory management registers. At present
  1600.         you are restricted to looking at the registers for
  1601.         the pages allocated to processes, which under EMMOS
  1602.         should be the only ones to change.
  1603.         The registers are automatically split into their
  1604.         composite fields for displaying
  1605.         and changing. To go forward to the next field, type
  1606.         <space>, to go to the next page, type <tab> and to
  1607.         exit type <return>. Numeric fields are changed by
  1608.         typing a number followed by <return>, other fields
  1609.         are changed by typing one character.
  1610.         the expansion direction, ed> is either up=u or down=d
  1611.         the access control is either  non resident  = n
  1612.                                       read only     = r
  1613.                                   or  read/write    = w
  1614.         an access control of 'unused' indicated an error
  1615.         in the memory management registers. The written into
  1616.         bit cannot be examined or changed.
  1617.  
  1618. b    set a breakpoint
  1619.  
  1620.     b 'l'    puts a breakpoint at location 'l'. Note 
  1621.         that you are not allowed to place a breakpoint
  1622.         on top of another breakpoint. It
  1623.         is possible to set breakpoints on top of emt
  1624.         instructions, but, once they have been
  1625.         reached, it is not possible to 
  1626.         continue or single step from them.
  1627.  
  1628. k    kill a breakpoint
  1629.  
  1630.     k 'l'    kills the breakpoint at location 'l'. If
  1631.         the program is halted at the breakpoint, it
  1632.         is not possible to continue from there, use 
  1633.         'go' instead.
  1634.     k *    kills all breakpoints. If the program had
  1635.         halted at a breakpoint it will not be
  1636.         possible to continue, use 'go' instead.
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.                                    28
  1652.  
  1653. cont.
  1654.  
  1655.  
  1656. g    go to command
  1657.  
  1658.     g 'l'    jumps to location 'l' and starts
  1659.         executing. 'l' must be a virtual address,
  1660.         mapped according to the window. The
  1661.         registers are loaded as set.
  1662.     gs 'l'    as above, but single stepping. Only one
  1663.         instruction is executed before control is
  1664.         returned to MUD. When single stepping all
  1665.         breakpoints are temporarily removed, so no
  1666.         breakpoints as such will be hit.
  1667.  
  1668. c    continue command
  1669.  
  1670.     c    continue from the breakpoint last reached or at the
  1671.         next instruction if previously single stepping.
  1672.     cs    as for continue but single stepping 
  1673.         ( see 'gs' above )
  1674.  
  1675.         Note that it is not possible to continue from a
  1676.         breakpoint that has just been killed, but you can
  1677.         use 'g' instead with 'l' as the contents of the program
  1678.         counter, R7.
  1679.  
  1680. i    change I/O command
  1681.  
  1682.         This command has a special syntax, because it is
  1683.     used to redirect the input and output of MUD from one
  1684.     terminal to another.
  1685.  
  1686.     i    change I/O to the console
  1687.     iv 'n'    change I/O to vdu 'n'
  1688.     is    sink the output. All output will be thrown away,
  1689.         including echoing. Input remains on the same channel.
  1690.  
  1691. f    find a value
  1692.  
  1693.     f 'v'    searches the physical memory, stating at
  1694.         location zero, for a word containing the value
  1695.         'v'. Every so often a message will say
  1696.         "still looking" if one has'nt been found
  1697.         yet. To stop the search early hit <escape>
  1698.         to break in.
  1699.     f 'v' 'l'
  1700.         As above but the search starts at 'l' 
  1701.         instead of zero.
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.                                    29
  1711.  
  1712. cont.
  1713.  
  1714.  
  1715. e    evaluate an expression
  1716.  
  1717.         This command evaluates an 18 bit expession, using octal
  1718.     or decimal numbers or the contents of a relocation register. There
  1719.     is one accumulator, acc, which holds an 18 bit number. The operations
  1720.     that can be performed on it are:
  1721.  
  1722.     ^ val    Load the acc with 'val'
  1723.     + val    Add 'val' into the acc
  1724.     - val    Subtract 'val' from the acc
  1725.     P    Convert the least significant 16 bits of acc into an
  1726.         18 bit virtual address
  1727.     V    Treat the value in acc as an 18 bit physical address and
  1728.         convert it into a 16 bit virtual address.
  1729.  
  1730.     The values are given by:
  1731.  
  1732.     # octal number    - an 18 bit octal number, the # can be omitted
  1733.     $ decimal number- a 15 bit decimal number, ie positive only
  1734.     R num        - the 18 bit value of relocation register 'num',
  1735.               num is 1 by default
  1736.  
  1737.         Several commands can appear on one line, seperated by commas
  1738.     or spaces if it is necessary to avoid ambiguity. The value in acc is
  1739.     displayed when the end of the line is reached.
  1740.  
  1741.         The value in acc is zero the first time the 'e' command is
  1742.     used. Subsequently the value is that left in it after the last use
  1743.     of 'e'.
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.  
  1751.  
  1752.  
  1753.  
  1754.  
  1755.  
  1756.  
  1757.  
  1758.  
  1759.  
  1760.  
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766.  
  1767.  
  1768.  
  1769.                                    30
  1770.  
  1771.     2.2.6    Using MUD
  1772.  
  1773.      If  RESMUD  is  linked  in  before  EMMPM  and MUD is present as an
  1774. overlay,  then  the  debugger  will  be entered once the system has been
  1775. loaded. If not the debugger cannot be used.
  1776.  
  1777.      When  control  is passed from MUD to the user program, by using the
  1778. go  or  continue  commands,  the  system error traps are set so that any
  1779. error  will  be  handled  by MUD. This remains so until the user program
  1780. changes  them.  Note  that  while  MUD  is  running the traps are set to
  1781. different handlers which detect whether the debugger itself is in error.
  1782. If  so  check  that  RESMUD  has  been  assembled  with the current page
  1783. configuration.
  1784.  
  1785.      We can return to the debugger at any time via the console emulator.
  1786. Find  the  address of the global symbol $MUDIN, it is part of RESMUD and
  1787. so  is  permanently  resident,  it's  virtual  and  physical  address is
  1788. therefore  the  same.  Use the console emulator to jump to this location
  1789. and MUD will restart.
  1790.  
  1791.  
  1792.  
  1793.  
  1794.  
  1795.  
  1796.  
  1797.  
  1798.  
  1799.  
  1800.  
  1801.  
  1802.  
  1803.  
  1804.  
  1805.  
  1806.  
  1807.  
  1808.  
  1809.  
  1810.  
  1811.  
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817.  
  1818.  
  1819.  
  1820.  
  1821.  
  1822.  
  1823.  
  1824.  
  1825.  
  1826.  
  1827.  
  1828.                                    31
  1829.  
  1830.     2.3    Linker and Loader Functions
  1831.     ___________________________________
  1832.  
  1833.      In  general  a  system's  linker  and  loader perform two logically
  1834. distinct   functions,  though  in  practice  the  border  between  these
  1835. functions  may  be  less clear. In a virtual memory system it is usually
  1836. the  operating  system  that allocates physical memory, but in a monitor
  1837. system  this  may be done by the linker. There are a number of functions
  1838. that  the  linker and loader are required to perform on an EMMOS system.
  1839. Some  of  these  functions  require a degree of intelligence that is not
  1840. usually  found in either linkers or loaders. These intelligent functions
  1841. may  be  incorporated in either the linker or the loader, or distributed
  1842. between  them. When presenting these functions we will describe them all
  1843. as being part of the linker, for ease of understanding. The loader then,
  1844. just copies an output image file from the linker, word for word into the
  1845. 128K  physical  memory.  However,  linkers  are complex pieces of system
  1846. software, that are difficult to write or modify. Therefore, in practice,
  1847. one usually takes the best of the functions that the linker has to offer
  1848. and  writes  a  loader  program  which  incorporates those remaining.The
  1849. functions that the linker/loader must perform are listed below:
  1850.  
  1851.     1.    Resolve all global references and relocate the 
  1852.         object code.
  1853.     2.    Allocate physical memory for the system, buffers,
  1854.         process code and stacks. This takes into account
  1855.         the page configuration scheme.
  1856.     3.    Construct a Load Map which specifies where processes
  1857.         are in physical memory and where the ends of their
  1858.         stacks are in virtual memory. This is passed on to the
  1859.         loaded system.
  1860.  
  1861.     2.3.1 The Linker
  1862.  
  1863.      We  can consider the input to the linker to be a set of Relocatable
  1864. Binary  (  RLB  )  modules, with some system of reference resolving that
  1865. need  not  concern  us.  A  process'  body is made up of one or more RLB
  1866. modules,  with  sharing allowed. EMMOS is similarly composed. To specify
  1867. how  the  system and process bodies are constructed we supply the linker
  1868. with  a  Link  Control  File,  which specifies which modules make up the
  1869. system  and process bodies, and the order in which they are to be linked
  1870. to  form  the body. We also need a way of uniquely identifying a process
  1871. body, so that when we create a process we can specify which code body to
  1872. use.
  1873.  
  1874.      Here we give an example of what this file could look like. The line
  1875. headed  'SYSTEM' would define the construction of the resident operating
  1876. system  part  of  EMMOS  and  lines  headed 'BODY' would each describe a
  1877. process body, it's name given in brackets:
  1878.  
  1879.     SYSTEM:        EMMPM-EMMTTY-..........-EMMMEM;
  1880.     BODY(X25):    X25CODE;
  1881.     BODY(PRINTR):    IOCODE-IOLIB;
  1882.     END:
  1883.  
  1884.  
  1885.  
  1886.  
  1887.                                    32
  1888.  
  1889. cont.
  1890.  
  1891.      The EMMOS linker must also allocate physical memory for the process
  1892. code  bodies and stacks. In order to do this it needs to know which code
  1893. bodies  will be incarnated as which processes and how much stack to give
  1894. those processes.T This information could go in the Link Control File. As
  1895. an  example of how it could be represented, we consider the example body
  1896. description given above, and create some processes with those bodies:
  1897.  
  1898.     PROC(X25-A):    "X25"   ,SYSTEM=200
  1899.     PROC(X25-B):    "X25"    ,SYSTEM=200
  1900.     PROC(PRINTR):    "PRINTR",SYSTEM=100,CORAL=400
  1901.     END:
  1902.  
  1903.      Here  we  describe three processes, called X25-A, X25-B and PRINTR.
  1904. The  first two are both incarnations of the body "X25" and both have 200
  1905. words  for their system stack and no CORAL stack. It's not necessary for
  1906. them  to  have  the  same size stacks, though some implementations could
  1907. impose  this as a restriction with no great hardship. The third process,
  1908. "PRINTR",  is  the one and only incarnation of the body "PRINTR". It has
  1909. 100 words for it's system stack and 400 words for it's CORAL stack.
  1910.  
  1911.      The  linker  still  requires  information on the page configuration
  1912. before it can allocate physical memory. This information is not strictly
  1913. necessary. We could allocate the code and stacks for each process as one
  1914. lump  of  physical  store  and if it is too large for the configuration,
  1915. then  the  system  will fail at run time. By knowing the page allocation
  1916. scheme  however,  the  linker  can be quite subtle and avoid unnecessary
  1917. duplication of code and could even arrange for the code and stacks to be
  1918. on separate pages if the sizes are right. ( For more details see 3.2.7/8
  1919. ).   To  complete  our  example  we  shall  give  an  idea  of  how  the
  1920. configuration could be specified in the Link Control File:
  1921.  
  1922.     PROCS 5..6,    BUFFERS 0..2,    EMMOS 3..4;
  1923.  
  1924.      Note that page 7 must always be allocated for the I/O page and that
  1925. the  section  using  page 0 will lose the first 1000 octal bytes for the
  1926. vector area.
  1927.  
  1928.      In  our  example,  if the body "X25" was less than 4K words then it
  1929. would  fit  on one memory page. Since the stacks for "X25-A" and "X25-B"
  1930. are  quite  small, they too fit on one page. The linker should then only
  1931. put one copy of the body into physical memory and arrange the mapping of
  1932. both  the processes such that page 5 maps onto it. Page 6 would map onto
  1933. the  processes  stack areas, which would of course be different physical
  1934. memory locations.
  1935.  
  1936.      Once the linker has finished allocating physical memory it needs to
  1937. be  able to tell the EMMOS initializer what the memory management window
  1938. for each process is and where it's stacks are. It does this by including
  1939. a  table  with  this  information in, in the Load Image File. This table
  1940. must  be  loaded at a place in memory where the initializer can find it,
  1941. say somewhere in the global buffer pool.
  1942.  
  1943.  
  1944.  
  1945.  
  1946.                                    33
  1947.  
  1948.     2.3.2 The Loader
  1949.  
  1950.      The  Loader  takes  the  Load  Image  file  as  input. This file is
  1951. produced  by  the  linker  and  contains  absolute  binary  data with an
  1952. indication  of  where in physical memory to load it. The loader need not
  1953. know  anything  about the processes or the system it is loading. However
  1954. there needs to be some way of telling where the system's entry point is.
  1955. Note  that  since  the  entry  point  will  be  a  virtual address it is
  1956. necessary  to  include  an  initial  memory  mapping  as  part  of  it's
  1957. definition.
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.  
  1988.  
  1989.  
  1990.  
  1991.  
  1992.  
  1993.  
  1994.  
  1995.  
  1996.  
  1997.  
  1998.  
  1999.  
  2000.  
  2001.  
  2002.  
  2003.  
  2004.  
  2005.                                    34
  2006.  
  2007.  
  2008.  
  2009.  
  2010.  
  2011.  
  2012.  
  2013.  
  2014.  
  2015.  
  2016.  
  2017.  
  2018.  
  2019.  
  2020.                 PART THREE
  2021.                 __________
  2022.  
  2023.                HOST MACHINE ASPECTS
  2024.  
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044.  
  2045.  
  2046.  
  2047.  
  2048.  
  2049.  
  2050.  
  2051.  
  2052.  
  2053.  
  2054.  
  2055.  
  2056.  
  2057.  
  2058.  
  2059.  
  2060.  
  2061.  
  2062.  
  2063.  
  2064.                                    35
  2065.  
  2066.     3.1     Linking Using the RSX Task Builder
  2067.     ___________________________________________
  2068.  
  2069.      The  RSX  task  builder( TKB ) is used as the linker. It is because
  2070. not  all  the functions we require are supplied by this linker, that our
  2071. loader  is  more  complicated  then  usual.  The Task Builder is used to
  2072. perform  the  relocating  and  global  reference  resolving parts of the
  2073. required  actions.  The  physical memory allocation, process incarnation
  2074. and the production of the Load Map are all actions that are performed by
  2075. our  loader.  This  does  mean  that the loader is complicated, but less
  2076. overall  effort  is required to write it than to completely re-write the
  2077. linker.
  2078.  
  2079.     3.1.1 Use of the Task Builder
  2080.  
  2081.      The task builder is able to handle overlays in several ways. It can
  2082. produce  disk resident overlays, in which "paged-out" segments reside on
  2083. disk,  or  memory  resident  overlays,  in  which all segments reside in
  2084. physical memory but not all are "paged-in" into virtual memory. TKB will
  2085. also  allow  your  task  to be some combination of the two. Overlays are
  2086. paged in and out by special calls to RSX which TKB automatically inserts
  2087. into  the  object code. It is possible to instruct TKB to leave out this
  2088. code,  allowing  the  user  to  handle  his  own  paging.  Overlays  are
  2089. characterized by being relocated at the same place in memory. it is this
  2090. feature  that EMMOS exploits to get all the process' bodies relocated at
  2091. the  same  base  address. We do however require that the linker does not
  2092. put any auto loading code in for the overlays.
  2093.  
  2094.      Amongst  the various tables hidden in the task image, is the window
  2095. description  table,  this does not appear for disk resident overlays, so
  2096. we  chose  to  use memory resident overlays throughout. Also, when using
  2097. memory resident overlays, each layer of the overlay tree is relocated on
  2098. a  page  boundary,  which  is another requirement for EMMOS. There is an
  2099. option,  when  running a task under RSX, of allowing it to be swapped in
  2100. and out of physical memory ( checkpointed ). A checkpointable task has a
  2101. large  space in it's task image file, so as EMMOS has no need of it, the
  2102. task  must  be  built not checkpointable ( /-CP switch ). We will assume
  2103. then  that the task is not checkpointable, with manually loaded ( though
  2104. we shall not include the calls to do it ) memory resident overlays.
  2105.  
  2106.  
  2107.  
  2108.  
  2109.  
  2110.  
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118.  
  2119.  
  2120.  
  2121.  
  2122.  
  2123.                                    36
  2124.  
  2125.      The first snag is met when we try to get information about the size
  2126. of  the  overlays  and  their position within the task image. The tables
  2127. that  contain  this information follow on directly after the code of the
  2128. root  segment,  but  there  is no indication as to how long the root is,
  2129. except  in  these  tables.  Normally their position is known because the
  2130. overlay  loading  mechanism  references  them,  but we've done away with
  2131. this.  Ideally  the root segment would be the EMMOS system, but there is
  2132. no  clean way of finding out how long it is, so we chose to not allocate
  2133. page  0  to  the  system.  Instead the root segment does not contain any
  2134. code,   only   some   tables   of  known  length  used  by  the  loader.
  2135. Unfortunately,  because TKB will relocate the next overlay layer on page
  2136. 1,  we  have  used up 4K of virtual space just for the interrupt vectors
  2137. etc.  To  avoid  this  we allocate the global buffer pool space to pages
  2138. 0,1....  because  no  code  is  loaded  for  it.  The problem remains to
  2139. persuade  TKB  to  relocate EMMOS at the end of the buffers. We could do
  2140. this  by  extending  the root segment to occupy all these pages and then
  2141. just ignore it all when loading, but this would mean the task image file
  2142. would  be  enormous.  Instead we use dummy overlay layers. Although each
  2143. layer  contains  only  one  word,  it  is  sufficient to persuade TKB to
  2144. relocate the next layer at the next page boundary.
  2145.  
  2146.      It  is  because  of  such  devious  means  of  getting  the overlay
  2147. relocated  to  the  desired base, that all the calculations performed by
  2148. TKB  to  produce  physical memory load addresses are useless. Instead of
  2149. wasting  large areas of physical memory the loader does the calculations
  2150. again. This also means that we can handle the process' stacks nicely.
  2151.  
  2152.      Finally  there is the problem of uniquely identifying each overlay,
  2153. so  a  process can specify which is to be it's code body. TKB gives each
  2154. overlay  a  name,  which is the first six characters of the first object
  2155. file's name in the overlay, however this may not be unique. We have then
  2156. two  options;  use  the  name  given  by TKB or use a position numbering
  2157. scheme. Despite it's drawbacks of non-uniqueness, the former was chosen.
  2158. Names  are easier to understand then numbers, and the possible inclusion
  2159. of  the  debugger  may  well upset the numbering, though it is a special
  2160. case.  The  use  of six character names for the overlays led us to adopt
  2161. the  <name> field of the $CREAP macro to specify which code body to use.
  2162. Other schemes may require another field in the macro call.
  2163.  
  2164.  
  2165.  
  2166.  
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.  
  2174.  
  2175.  
  2176.  
  2177.  
  2178.  
  2179.  
  2180.  
  2181.  
  2182.                                    37
  2183.  
  2184.     3.1.2 The Format of the Task Image File
  2185.  
  2186.      The  information required to complete the Overlay Description Table
  2187. is  scattered  across  the  first few blocks of the task image file. The
  2188. format  is  dependant  on various switches and the form of the ODL file.
  2189. There  follows  a brief description of the parts relevant to the loader,
  2190. assuming it was built in the required manner.
  2191.  
  2192.  
  2193. BLOCK 0:
  2194.  
  2195.          Contains no useful information, except perhaps the creation
  2196.     date of the task image.
  2197.  
  2198. BLOCK 1:
  2199.  
  2200.     No useful information.
  2201.  
  2202. BLOCK 2:
  2203.  
  2204.          This  is  the  start  of  the task header. The word at byte
  2205.     offset  72  octal  is  the  "header  guard  word  pointer". This
  2206.     contains  the  byte offset, within the next block, of the "guard
  2207.     word", this immediatly preceeds the code of the root segment and
  2208.     is how the loader finds the root.
  2209.  
  2210. BLOCK 3:
  2211.  
  2212.          This contains the start of the root segment. The first word
  2213.     of  the  root follows the "guard word". The root segment is used
  2214.     to  transmit  configuration  details and the process description
  2215.     table  to  the  loader.  Immediatly following these tables is 29
  2216.     words  of  rubbish ( code used to load the overlays under RSX ),
  2217.     the  segment  descriptor table, one word of rubbish and then the
  2218.     window  descriptor  table.  These  two tables are used by RSX to
  2219.     define the positions of the memory resident overlays in physical
  2220.     memory,  EMMOS  uses  them  to construct the Overlay Description
  2221.     Table, as follows:
  2222.  
  2223.     segment descriptor table -
  2224.     each entry is 9 words long, there is one entry for each overlay and
  2225.     the root
  2226.         word offset 1    the virtual base address
  2227.         word offset 6&7    the segment's name in radix 50 format.
  2228.  
  2229.     window descriptor table -
  2230.     each entry is 10 words long, there is one entry for each overlay
  2231.         word offset 2    overlay's size in memory blocks (64bytes)
  2232.  
  2233.  
  2234. NEXT BLOCK BOUNDARY:
  2235.  
  2236.          The  code  of the first overlay begins at the first word of
  2237.     the   next  disk  block.  Subsequent  overlays  start  on  block
  2238.     boundaries following on in order.
  2239.  
  2240.  
  2241.                                    38
  2242.  
  2243.     3.1.3 The Overlay Description Language
  2244.  
  2245.      The  Task  Builder  takes  a  series of object files and links them
  2246. together  to produce a Task Image. This is the exact image of what is to
  2247. be  loaded at run time ( under RSX ). EMMOS exploits the memory resident
  2248. overlay capabilities of the Task Builder in order to relocate the system
  2249. kernel  and  processes'  bodies in the desired place. The arrangement of
  2250. the  overlays  is  described in the Overlay Description Language ( ODL )
  2251. file, the structure of which is as follows:
  2252.  
  2253.     module1 - module2 - ............ - moduleN
  2254.  
  2255.      specifies  that  the  N modules are to be concatenated in the given
  2256. order
  2257.  
  2258.     ( module1, module2, ............ , moduleN )
  2259.  
  2260.      specifies  that  the  N  modules will overlay each other in virtual
  2261. memory.  The  modules  not paged-in will be resident on disk or, if they
  2262. are  memory resident overlays ( indicated by a ! before the open bracket
  2263. ), in physical memory.
  2264.  
  2265.      These concatenation and overlay operations are combined to describe
  2266. the overlay tree structure, eg:
  2267.  
  2268.     A - B - !( C - D - !( E , F ) , G - !( H - !( I , J ) , K ) , L )
  2269. this specifies the following tree
  2270.     E   F    I   J
  2271.     |___|    |___|
  2272.       D        H     K
  2273.       |        |_____|
  2274.       C           G          L
  2275.       |___________|__________|
  2276.            B
  2277.            |
  2278.            A
  2279.  
  2280.      At  any  one  time  during  runtime,  the memory will contain those
  2281. modules lying on one of the paths from the root to a leaf.
  2282.  
  2283.      For  ease  of  writing, it is possible to give parts of the overlay
  2284. tree  a name, using the factor command ( .FCTR ). so a complete ODL file
  2285. for the above example could be:
  2286.  
  2287.     .ROOT        A - B - !( OV1 , OV2 , L )
  2288.     OV1:    .FCTR    C - D - OV11
  2289.     OV2:    .FCTR    G - !( OV22 , K )
  2290.     OV11:    .FCTR    !( E , F )
  2291.     OV22:    .FCTR    H - !( I , J )
  2292.     .END
  2293.  
  2294.  
  2295.  
  2296.  
  2297.  
  2298.  
  2299.  
  2300.                                    39
  2301.  
  2302.     3.1.4 The EMMOS ODL File
  2303.  
  2304.  
  2305.     .ROOT        ROOT - !( OV1 - !( OV2 - !( EMMOS - !( PROCS ) ) ) )
  2306.     EMMOS:    .FCTR    EMMPM - FIRST - ......................
  2307.     PROCS:    .FCTR    BODY1 , BODY2 , ..............., BODYn
  2308.  
  2309.      The  factor  EMMOS  describes all the system modules, which are all
  2310. concatenated.  The  factor  PROCS  describes  each of the different code
  2311. bodies  for  the processes. Normally only one code body is required at a
  2312. time  so  the  modules  overlay  each  other,  but  it  is  possible  to
  2313. concatenate processes which are to access common routines.
  2314.  
  2315.      For  example,  suppose  we have four code bodies BODY1, ... , BODY4
  2316. which  are each $CREAPed only once to give processes PROC1, ... , PROC4.
  2317. If these processes are completely independant then we write:
  2318.  
  2319.     PROCS:    .FCTR    BODY1 , BODY2 , BODY3 , BODY4
  2320.  
  2321.      Suppose  we have a library module, LIB, that is shared by PROC1 and
  2322. PROC2, then we could write:
  2323.  
  2324.     PROCS:    .FCTR    BODY1 - LIB , BODY2 - LIB , BODY3 , BODY4
  2325.  
  2326.      This  would  cause  two  copies of LIB to be in physical memory. We
  2327. could however write:
  2328.  
  2329.     PROCS:    .FCTR    BODY1 - BODY2 - LIB , BODY3 , BODY4
  2330.  
  2331.      which  would cause one copy of LIB to be put in the task image, but
  2332. PROC1  and  PROC2  would  now  be  paged  in  and  out of virtual memory
  2333. together, which may not be desirable.
  2334.  
  2335.      Note that if the total size of BODY1, BODY2, LIB and the stacks for
  2336. PROC1  and  PROC2  exceeds  the  space  allocated to processes, then the
  2337. loader  will  duplicate  some or all of the code in an attempt to fit it
  2338. in. It may be then, that more physical memory would be used in trying to
  2339. share LIB than if we specified duplication in the first place.
  2340.  
  2341.  
  2342.  
  2343.  
  2344.  
  2345.  
  2346.  
  2347.  
  2348.  
  2349.  
  2350.  
  2351.  
  2352.  
  2353.  
  2354.  
  2355.  
  2356.  
  2357.  
  2358.  
  2359.                                    40
  2360.  
  2361. cont.
  2362.  
  2363.      The modules ROOT, OV1, OV2, ..... OVn are required by the system to
  2364. ensure that the operating system and the process bodies are relocated in
  2365. the correct place. ROOT also transmits information from the $CREAP macro
  2366. calls to the loader. The Task Builder relocates the first "layer" of the
  2367. overlay  tree  (  the  root  )  at location zero. Successsive layers are
  2368. relocated  at  the  start of the next page boundary ( a page is 4K words
  2369. long  ).  So,  because  each  of  these  modules is quite small, ROOT is
  2370. relocated  at  0,  OV1  at  20000,  OV2  at 40000 etc. If we require the
  2371. operating system to be relocated at 60000, we put it in the next layer (
  2372. as  in  the  above example ). Suppose we want EMMOS to start on page 4 (
  2373. location 100000 ), and it is over one page long so the processes will be
  2374. on page 6 ( location 140000 ), we would need to pack out pages 0..3 thus
  2375.  
  2376. .ROOT    ROOT - !( OV1 - !( OV2 - !( OV3 - !( EMMOS - !( PROCS ) ) ) ) )
  2377.  
  2378.      For  technical  reasons  it  was not possible to have the operating
  2379. system  at  the low numbered end of memory, so that is where the buffers
  2380. have  been  put.  Dummy  overlays  are  used  to pad out the buffer area
  2381. because  they  cause  the task image to be much smaller than if we had a
  2382. .BLKW . The latter would cause it to contain about 12K of zeroes!
  2383.  
  2384.  
  2385.  
  2386.  
  2387.  
  2388.  
  2389.  
  2390.  
  2391.  
  2392.  
  2393.  
  2394.  
  2395.  
  2396.  
  2397.  
  2398.  
  2399.  
  2400.  
  2401.  
  2402.  
  2403.  
  2404.  
  2405.  
  2406.  
  2407.  
  2408.  
  2409.  
  2410.  
  2411.  
  2412.  
  2413.  
  2414.  
  2415.  
  2416.  
  2417.  
  2418.                                    41
  2419.  
  2420.     3.1.5 Installation of the Debugger
  2421.  
  2422.      The  EMMOS  debugger,  MUD, is in two parts, a resident part RESMUD
  2423. and  an overlay part MUD. To be able to use the debugger both parts must
  2424. be included in the ODL file. RESMUD must appear before EMMOS but MUD can
  2425. be put anywhere amongst the PROCS, eg:
  2426.  
  2427. .ROOT    ROOT - !( OV1 - !( OV2 - !( RESMUD - EMMOS - !( PROCS , MUD ) ) ) )
  2428.  
  2429.     3.1.6 Creating the Task Image File
  2430.  
  2431.      Once  the form of the ODL file has been worked out the task builder
  2432. is run under RSX-11 by:
  2433.  
  2434.     TKB    EMMOS , EMMOS /NOSP = EMMOS /MP
  2435.  
  2436.      The  first  output  file  is  for the Task Image ( .TSK ) file, the
  2437. second  is  the task map ( .MAP ) file, which is spooled by default. The
  2438. MP switch specifies that the input file is an .ODL file.
  2439.  
  2440.      The  .MAP  shows  the  structure  of  the  task image and gives the
  2441. virtual  addresses of the modules, global symbols and .PSECTs. This link
  2442. map  should  be  used  in  conjunction with the loader's load map, which
  2443. specifies  physical  addresses  of  code and stacks, when debugging. The
  2444. .TSK file now needs to be copied to the RT-11 format disk which contains
  2445. the loader using FLX. The system is now ready for loading and running.
  2446.  
  2447.  
  2448.  
  2449.  
  2450.  
  2451.  
  2452.  
  2453.  
  2454.  
  2455.  
  2456.  
  2457.  
  2458.  
  2459.  
  2460.  
  2461.  
  2462.  
  2463.  
  2464.  
  2465.  
  2466.  
  2467.  
  2468.  
  2469.  
  2470.  
  2471.  
  2472.  
  2473.  
  2474.  
  2475.  
  2476.  
  2477.                                    42
  2478.  
  2479.     3.2    The EMMOS RSX Task Image Loader
  2480.     _______________________________________
  2481.  
  2482.      This section describes the operation of the loader for the Extended
  2483. Memory  MOS  system.  The  loader itself is loaded from a floppy disk in
  2484. RT-11 format, using a fairly standard bootstrap loader. The EMMOS loader
  2485. then loads the system from an RSX-11 Task Builder Image file ( stored in
  2486. RT-11  format  )  on the same floppy disk. Control is then passed to the
  2487. operating system or to the EMMOS debugger, MUD, if it is loaded.
  2488.  
  2489.  
  2490.  
  2491.  
  2492.  
  2493.  
  2494.  
  2495.  
  2496.  
  2497.  
  2498.  
  2499.  
  2500.  
  2501.  
  2502.  
  2503.  
  2504.  
  2505.  
  2506.  
  2507.  
  2508.  
  2509.  
  2510.  
  2511.  
  2512.  
  2513.  
  2514.  
  2515.  
  2516.  
  2517.  
  2518.  
  2519.  
  2520.  
  2521.  
  2522.  
  2523.  
  2524.  
  2525.  
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531.  
  2532.  
  2533.  
  2534.  
  2535.  
  2536.                                    43
  2537.  
  2538.     3.2.1 Inputs and Outputs
  2539.  
  2540.      The input to the loader is an RSX-11 Task Builder Image file stored
  2541. on a floppy disk in RT-11 format. This file contains:
  2542.  
  2543.     1.    The Configuration Table     ( see 3.2.3 )
  2544.     2.    The Overlay Description Table    ( see 3.2.4 )
  2545.     3.    The Process Description Table    ( see 3.2.5 )
  2546.     4.    Absolute binary code for the operating system
  2547.             and processes.
  2548.  
  2549.      The  loader  produces  a  table,  the  load map, which it places in
  2550. memory  and  displays  on the console, that describes the positioning of
  2551. all the processes in physical memory.
  2552.  
  2553.      The  address of the entry point to the loaded system must be stored
  2554. in  the  first  word  of  the  system.  This  is set by MOSPM or, if the
  2555. debugger is included, RESMUD.
  2556.  
  2557.  
  2558.  
  2559.  
  2560.  
  2561.  
  2562.  
  2563.  
  2564.  
  2565.  
  2566.  
  2567.  
  2568.  
  2569.  
  2570.  
  2571.  
  2572.  
  2573.  
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580.  
  2581.  
  2582.  
  2583.  
  2584.  
  2585.  
  2586.  
  2587.  
  2588.  
  2589.  
  2590.  
  2591.  
  2592.  
  2593.  
  2594.  
  2595.                                    44
  2596.  
  2597.     3.2.2 The Console Load Map
  2598.  
  2599.      This  is  a human readable form of the LOAD MAP that is supplied to
  2600. the  loaded  system.  There  is one line for each process describing the
  2601. position of it's code and stacks.
  2602.  
  2603.      The  first  column  gives  the process id ( pid ), the next two the
  2604. limits of the code and the fourth the limits of the two stacks combined.
  2605.  
  2606.      If  none  of  the pages containing code, contain any stack then the
  2607. third  column  will  read  "unshared",  that  is,  there is no page that
  2608. contains  both  stack  and  code. However, if there is only one page for
  2609. processes then this must contain all the code and all the stack, in this
  2610. case the third column will read "page is shared".
  2611.  
  2612.      If  the code is longer than one page, and it is necessary to have a
  2613. page  containing  both stack and code, then the third column will be the
  2614. limits of the piece of code that is sharing with the stacks. This may be
  2615. a copied piece of code.
  2616.  
  2617.      The limits are given in terms of physical memory blocks, so a limit
  2618. of
  2619.  
  2620.         001200 - 001250
  2621.  
  2622.      for  the  code  would  mean that the code starts at physical memory
  2623. location 120000 and ends somewhere between 125000 and 125077.
  2624.  
  2625.      If  the task image does not contain an overlay for a process' body,
  2626. then the load map entry for that process will be of the form:
  2627.  
  2628.     pid  -  ABCDEF has'nt got a body
  2629.  
  2630.      If  one  or  more  processes  lack  bodies  then  the  load will be
  2631. abandoned, once the load map has been printed, with the message:
  2632.  
  2633.     "process requires body"   (see ERRORS)
  2634.  
  2635.      Note:  the  printing  of  the  Load Map can be abandoned by hitting
  2636. <escape>.
  2637.  
  2638.  
  2639.  
  2640.  
  2641.  
  2642.  
  2643.  
  2644.  
  2645.  
  2646.  
  2647.  
  2648.  
  2649.  
  2650.  
  2651.  
  2652.  
  2653.  
  2654.                                    45
  2655.  
  2656.     3.2.3 The Configuration Table
  2657.  
  2658.      This  table  resides  in  the  root  segment  of  the  task  image,
  2659. immediately before the Process Description Table. It is used to tell the
  2660. loader  the  page allocation scheme and the maximum number of processes.
  2661. The  information is passed to it at run time so that the loader need not
  2662. be re-compiled for every change in the configuration.
  2663.  
  2664.     The format is:
  2665.  
  2666.     VAR config_table :RECORD
  2667.                 max_number_of_processes,
  2668.                 load_map_address,
  2669.                 first_mos_page, last_mos_page,
  2670.                 first_process_page, last_process_page
  2671.                     : INTEGER
  2672.             END;
  2673.  
  2674.  
  2675.  
  2676.  
  2677.  
  2678.  
  2679.  
  2680.  
  2681.  
  2682.  
  2683.  
  2684.  
  2685.  
  2686.  
  2687.  
  2688.  
  2689.  
  2690.  
  2691.  
  2692.  
  2693.  
  2694.  
  2695.  
  2696.  
  2697.  
  2698.  
  2699.  
  2700.  
  2701.  
  2702.  
  2703.  
  2704.  
  2705.  
  2706.  
  2707.  
  2708.  
  2709.  
  2710.  
  2711.  
  2712.  
  2713.                                    46
  2714.  
  2715.     3.2.4 The Overlay Description Table
  2716.  
  2717.      This  table  is  constructed  by  the  loader from the task image's
  2718. window and segment descriptor tables, that follow the root segment. Each
  2719. overlay named by the task image ( except the dummy ones and MOS ) has an
  2720. entry of the form:
  2721.  
  2722.     TYPE overlay_description = RECORD
  2723.                     name : ascii;
  2724.                     size : mem_blocks;
  2725.                     disk_address : INTEGER
  2726.                 END;
  2727.  
  2728.     TYPE ascii = ARRAY[ 1:6 ] OF CHAR;
  2729.  
  2730.     TYPE mem_blocks = 0..number_of_process_pages * #200 -1;
  2731.  
  2732. The table is given by
  2733.  
  2734.     odt : ARRAY[ 1..number_of_overlays ] OF overlay_description;
  2735.  
  2736.  
  2737. odt[ ov ].size    contains the size of the overlay segment ( that is of 
  2738. the code ) in 32 word memory blocks.
  2739. odt[ ov ].name is the overlay's name, taken from the overlay description
  2740. language file at build time.
  2741. odt[ ov ].disk_address is the number of the disk block where the overlay starts.
  2742.  
  2743.      Note that the disk address field is not used in the current version
  2744. of  the  loader. It remains as a left-over from a version that would not
  2745. support down line loading.
  2746.  
  2747.  
  2748.  
  2749.  
  2750.  
  2751.  
  2752.  
  2753.  
  2754.  
  2755.  
  2756.  
  2757.  
  2758.  
  2759.  
  2760.  
  2761.  
  2762.  
  2763.  
  2764.  
  2765.  
  2766.  
  2767.  
  2768.  
  2769.  
  2770.  
  2771.  
  2772.                                    47
  2773.  
  2774.     3.2.5 The Process Description Table
  2775.  
  2776.      This table resides in the root segment of the task image, following
  2777. the  Configuration  Table.  It is produced by the $CREAPs used to create
  2778. the  processes.  It  is  used  to  tell  the  loader which processes are
  2779. required,  which  overlay  will  supply  the  code and the size of their
  2780. stacks. There is one entry in the table per process, each of the form:
  2781.  
  2782.     TYPE process_description = RECORD
  2783.                     pid : INTEGER;
  2784.                     name : ascii;
  2785.                     r0_size, r6_size : mem_blocks
  2786.                 END;
  2787.  
  2788.     TYPE ascii = ARRAY [ 1..6 ] OF CHAR;
  2789.  
  2790.     TYPE mem_blocks = 0..number_of_process_pages * #200 - 1;
  2791.  
  2792. The table is given by
  2793.  
  2794.     VAR pdt : ARRAY [ 1..number_of_processes ] OF process_description;
  2795.  
  2796.  
  2797. pdt[ i ] is the entry for the ith process,
  2798. so pdt[ i ].pid = i for all i IN 1..number_of_processes. 
  2799. The name field contains the six character name of the overlay which is the
  2800. code for the process. This is taken from the second parameter of the $CREAP
  2801. macro call.
  2802. pdt[ i ].r0_size and pdt[ i ].r6_size contain the required sizes, in 32
  2803. word memory blocks, of the stacks.
  2804. Note that the macro converts the sizes from words to memory blocks before
  2805. placing the values in the table, using
  2806.     size_in_blocks := ceiling( size_in_words / 32 ).
  2807.  
  2808.  
  2809.  
  2810.  
  2811.  
  2812.  
  2813.  
  2814.  
  2815.  
  2816.  
  2817.  
  2818.  
  2819.  
  2820.  
  2821.  
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.                                    48
  2832.  
  2833.     3.2.6 The Load Map
  2834.  
  2835.      The  load map describes the loaded system to the initializer. It is
  2836. placed  in  memory  by  the  loader at an agreed address before it gives
  2837. control to the system. There is one entry in the table for each process,
  2838. and  a special one for the debugger if it is included in the task image.
  2839. The form of a table entry is:
  2840.  
  2841.     TYPE load_description = RECORD
  2842.                     pid,
  2843.                     r0_low, r0_hi,
  2844.                     r6_low, r6_hi : INTEGER;
  2845.                     window : ARRAY 
  2846.                         [ first_page..last_page ]
  2847.                         OF window_type
  2848.                 END;
  2849.  
  2850.     TYPE window_type = RECORD par, pdr : INTEGER END;
  2851.  
  2852. The map is given by:
  2853.  
  2854.     map : ARRAY [ 1..number_of_processes + 1 ] OF load_description
  2855.  
  2856.  
  2857.      map[i] is the entry for the ith process, so map[i].pid = i, for all
  2858. i IN 1..number_of_processes. map[i].pid = -1 for the debugger entry. Any
  2859. unused entries have pid = 0.
  2860.  
  2861.      r0_low  and  r0_hi contain the virtual byte addresses of the lowest
  2862. and  highest  numbered  words in the R0 ( CORAL ) stack for the process.
  2863. Similarly for r6_low, r6_hi.
  2864.  
  2865.      window describes the mapping from virtual memory onto this process.
  2866. There  are  two  words  for  each  page allocated to a process, the page
  2867. address register and the page descriptor register.
  2868.  
  2869.  
  2870.  
  2871.  
  2872.  
  2873.  
  2874.  
  2875.  
  2876.  
  2877.  
  2878.  
  2879.  
  2880.  
  2881.  
  2882.  
  2883.  
  2884.  
  2885.  
  2886.  
  2887.  
  2888.  
  2889.  
  2890.                                    49
  2891.  
  2892.     3.2.7 The Physical Memory Allocation Algorithm
  2893.  
  2894.      The  loader should attempt to arrange the loading of the Load Image
  2895. into  physical  memory  in a way that will reduce the amount of physical
  2896. memory  required.  The  total  amount  of  virtual memory allocated to a
  2897. process  for  it's  code body and stacks will be fixed ( = num_pp memory
  2898. pages  ), but for each process the sizes of it's code and the total size
  2899. of it's two stacks will vary.
  2900.  
  2901.      If  at  all possible the loader will arrange for the stacks and the
  2902. code to be on different pages in virtual memory, allowing the process to
  2903. put read-only protection on it's code. This is only possible if:
  2904.  
  2905.     pages( code_size ) + pages( stack_size ) <= num_pp
  2906.  
  2907.      where  pages(  i  )  = the size i rounded up into a whole number of
  2908. memory pages. Of course if pages( code_size + stack_size ) > num_pp then
  2909. not  enough virtual memory is availiable for this process. However if we
  2910. have:
  2911.  
  2912.     pages( code_size + stack_size ) = num_pp
  2913.  
  2914.      then some of the code and some of the stack space must share one of
  2915. the  pages. The shared page cannot then have read-only protection placed
  2916. on  it.  If  a process has already been created with this code body then
  2917. physical  memory  following  the code body will have been allocated as a
  2918. stack.  We  cannot  then  have  the stack for the next process following
  2919. directly  on  from  the code, so it may be necessary to copy part of the
  2920. code  body and arrange that the memory mapping maps the two parts of the
  2921. code onto consecutive virtual memory locations.
  2922.  
  2923.  
  2924.  
  2925.  
  2926.  
  2927.  
  2928.  
  2929.  
  2930.  
  2931.  
  2932.  
  2933.  
  2934.  
  2935.  
  2936.  
  2937.  
  2938.  
  2939.  
  2940.  
  2941.  
  2942.  
  2943.  
  2944.  
  2945.  
  2946.  
  2947.  
  2948.  
  2949.                                    50
  2950.  
  2951. E.G.
  2952.  
  2953.      Suppose  we have two pages for a process, num_pp = 2, and we have a
  2954. code  body which is $CREAPed twice, as PROC1 with stacks S1 and as PROC2
  2955. with stacks S2. If the code body is larger than one page then the second
  2956. page must be shared between the stacks and some of the code.
  2957.  
  2958.      First the loader copies the code body into physical memory, then it
  2959. allocates   the   stacks  for  PROC1,  the  window  for  PROC1  will  be
  2960. (a..b,b..d).
  2961.  
  2962.     --a---------------b----c------d----f---------------
  2963.       :    code size       :  S1  :        ....physical memory
  2964.     ---------------------------------------------------
  2965.       |<- 4K words -->|<-- 4K words -->|
  2966.  
  2967.      Now  for PROC2. If pages( code size + S1 + S2 ) <= num_pp, then the
  2968. loader  can  allocate  the stack following on directly from S1, thus the
  2969. window for PROC2 will be (a..b,b..e).
  2970.  
  2971.     ---a--------------b----c------d--e-f---------------
  2972.        :   code size       :  S1  :S2:
  2973.     ---------------------------------------------------
  2974.  
  2975.      Note  that  PROC2's  window  allows  it to ( illegally ) access the
  2976. stack  of  S1. If however pages( code size + S1 + S2 ) > num_pp then the
  2977. loader  must  take  a copy of the piece of code that overlaps the second
  2978. page,  (copy  from  b..c  to  d..g), thus the window for PROC2 will be (
  2979. a..b,d..h ), and the copy will be mapped into the same virtual locations
  2980. as the original.
  2981.  
  2982.     ---a--------------b----c------d--e-fg--h------------
  2983.        :   code size       :  S1  :copy :S2:
  2984.     ----------------------------------------------------
  2985.  
  2986.      Now  PROC1's stack is not in the window of PROC2 so neither process
  2987. can use the other's stack.
  2988.  
  2989.      The  loader  will  try  and fit as many stacks as possible into the
  2990. page  without  copying  a piece of code, but it wont try to optimize the
  2991. ordering.  If  the  code  size is smaller than a page and the stacks are
  2992. bigger then the whole of the code will be copied.
  2993.  
  2994.  
  2995.  
  2996.  
  2997.  
  2998.  
  2999.  
  3000.  
  3001.  
  3002.  
  3003.  
  3004.  
  3005.  
  3006.  
  3007.  
  3008.                                    51
  3009.  
  3010.     3.2.8 The Logical Operation of the Loader
  3011.  
  3012.  
  3013.     get process description table from task image;
  3014.     construct overlay description table;
  3015.     load EMMOS;
  3016.     FOR each overlay
  3017.     DO
  3018.         load the code;
  3019.         FOR each process
  3020.         DO
  3021.         IF name of process = name of overlay
  3022.         THEN
  3023.             IF size of code in pages + size of stacks in pages
  3024.             <= number of pages for processes
  3025.             THEN
  3026.             code and stacks are on completely different pages;
  3027.             set up the window for the process;
  3028.             leave room for the stacks in physical memory
  3029.  
  3030.             ELSF (size of code + stacks) in pages
  3031.             = number of pages for processes
  3032.             THEN
  3033.             one page contains stack and code;
  3034.             IF stack will fit on the end of the last
  3035.                incarnation's window
  3036.             THEN
  3037.                 leave room for the stacks after last stack;
  3038.                 set up the process' window
  3039.             ELSE
  3040.                 make a copy of the piece of code that must
  3041.                 share a page with some stack;
  3042.                 leave room for the stacks after the copied code;
  3043.                 set up the window for the process
  3044.             FI
  3045.             ELSE
  3046.             process is too large
  3047.             FI
  3048.         FI
  3049.         OD
  3050.     OD
  3051.  
  3052.  
  3053.  
  3054.  
  3055.  
  3056.  
  3057.  
  3058.  
  3059.  
  3060.  
  3061.  
  3062.  
  3063.  
  3064.  
  3065.  
  3066.  
  3067.                                    52
  3068.  
  3069.     3.2.9 Error Messages
  3070.  
  3071.     i. System Traps
  3072.  
  3073.          These  indicate  something  has gone drastically wrong with
  3074.     the  loader,  hopefully they will only occur after modifications
  3075.     have been made and not thoroughly tested. They may also occur if
  3076.     the  loaded  system  goes  wrong  before  it  has  set  the trap
  3077.     locations to its own trap handlers.
  3078.  
  3079. cpu error: pc = nnnnnn   ps = mmmmmm
  3080. reserved instruction: pc = nnnnnn   ps = mmmmmm
  3081.  
  3082.          These  messages  occur  when a trap to #004 and #010 occur.
  3083.     The contents of the program counter and processor staus word, as
  3084.     placed on the stack by the trap, are displayed.
  3085.  
  3086.  
  3087. memory management trap 250
  3088. nnnnnn at mmmmmm
  3089.  
  3090.          This  message  occurs  when  something  goes wrong with the
  3091.     memory  management. The contents of the two status registers are
  3092.     displayed.  nnnnnn  =  SR0  which  is  further  expanded in full
  3093.     following  the  error  message  ,  and mmmmmm = SR2, the virtual
  3094.     address   associated  with  the  error.  Following  the  written
  3095.     expansion  of  SR0,  the  contents  of  the  kernel  mode memory
  3096.     management registers are displayed.
  3097.  
  3098.  
  3099. power failed, start again
  3100.  
  3101.          the  power  to the processor failed, re-boot the system. NB
  3102.     this has not been tested!!!!
  3103.  
  3104.  
  3105.  
  3106.  
  3107.  
  3108.  
  3109.  
  3110.  
  3111.  
  3112.  
  3113.  
  3114.  
  3115.  
  3116.  
  3117.  
  3118.  
  3119.  
  3120.  
  3121.  
  3122.  
  3123.  
  3124.  
  3125.  
  3126.                                    53
  3127.  
  3128.     ii. Loader Errors and Messages
  3129.  
  3130.  
  3131. test: eof
  3132.  
  3133.     The end of the task builder image file has been reached prematurely.
  3134.  
  3135. test: get has failed
  3136.  
  3137.     An error occurred in the transfer of data from the floppy disk. Try
  3138.     again.
  3139.  
  3140. test: rewind
  3141.  
  3142.     The loader requires the input task image file to be rewound. This
  3143.     is only an error if the file is not on a rewindable device, eg down
  3144.     line loading. It is caused by an error in the loader.
  3145.  
  3146. cant find 'task file name'
  3147.  
  3148.     The file is not on the floppy disk, check the file name specified
  3149.     in the loader is the same as you copied to the disk, and the disk
  3150.     is in the correct drive ( drive 0 ). Remember that the name specified
  3151.     in the loader must include any blanks necessary to pack the name to
  3152.     10 chars, in the form ABCDEF.EXT
  3153.  
  3154. too short!
  3155.  
  3156.     The file is less than 4 blocks long, so cannot possibly be the 
  3157.     correct task image.
  3158.  
  3159. first dummy overlay not found
  3160.  
  3161.     the dummy overlay that is used to pack out the buffer area is not
  3162.     present in the task image. Check the file is a task image and that
  3163.     the ODL file correctly specifies the dummy overlays.
  3164.  
  3165. mos is larger than nn pages long
  3166.  
  3167.     the resident part of EMMOS is too large, more than the nn pages
  3168.     specified in the configuration file. Make sure that the processes
  3169.     have been put in as overlays and not in the resident  part.
  3170.  
  3171. window and segment descriptors of unequal size
  3172.  
  3173.     The loader has lost it's place in the task image, or the ODL file
  3174.     does not specify the overlays in the correct format.
  3175.  
  3176. ABCDEF is too large
  3177.  
  3178.     The named overlay is too large for the configuration, even without
  3179.     stacks. Check that the overlay names are seperated by commas in the ODL
  3180.     file.
  3181.  
  3182.  
  3183.  
  3184.  
  3185.                                    54
  3186.  
  3187.     Errors and Messages - cont.
  3188.  
  3189.  
  3190.  
  3191. process nn too large
  3192.  
  3193.     The process with pid = nn has stack and code too large for the
  3194.     configuration. Check that stack sizes have been given in words in
  3195.     the $CREAP macro call.
  3196.  
  3197. ABCDEF has'nt been made a process
  3198.  
  3199.     The named overlay does'nt appear in any of the $CREAPs. The overlay
  3200.     is loaded but otherwise ignored, this is not a fatal error.
  3201.  
  3202. process nn: code duplicated
  3203.  
  3204.     The loader was forced to make a copy of some of the process' code
  3205.     because the code had already been $CREAPed and the stack and code
  3206.     needs to share a page. This is not an error.
  3207.  
  3208. debugger has been loaded  nnnnnn - mmmmmm
  3209.  
  3210.     The overlay part of the debugger has been loaded, starting at
  3211.     memory block nnnnnn and finishing in block mmmmmm. This is not an
  3212.     error.
  3213.  
  3214. ABCDEF has incorrect base address = nnnnnn
  3215.  
  3216.     The named overlay has been relocated at nnnnnn by the Task Builder.
  3217.     This does not agree with the virtual page allocation scheme given.
  3218.     Check that the ODL file is correct, that the right number of dummy
  3219.     packing overlays are present and that all overlays are not too
  3220.     large for the configuration.
  3221.  
  3222. debugger is too large
  3223.  
  3224.     The debugger takes up more space than is allowed for processes. it
  3225.     is still loaded into physical memory, but only those pages normally
  3226.     allowed for processes will be paged into virtual memory, this will
  3227.     almost certainly cause MUD to crash. Use the console emulator to
  3228.     enter the system instead of MUD. Alternatively, remove the debugger
  3229.     or allow more pages for processes. This is not a fatal error.
  3230.  
  3231.  
  3232.  
  3233.  
  3234.  
  3235.  
  3236.  
  3237.  
  3238.  
  3239.  
  3240.  
  3241.  
  3242.  
  3243.  
  3244.                                    55
  3245.  
  3246.     Errors and Messages - cont.
  3247.  
  3248.  
  3249.  
  3250.  
  3251. the debugger cannot be used
  3252.  
  3253.     Either the resident part or the overlay part of the debugger are
  3254.     missing and hence the debugger cannot be used. If the debugger is
  3255.     needed then include the missing name in the ODL file. This is not a 
  3256.     fatal error.
  3257.  
  3258. non-unique overlay  ABCDEF
  3259.  
  3260.     The ODL file describes a configuration such that two overlays have
  3261.     the same name. The loader requires all overlays to have unique
  3262.     names so it can unambiguously select the code body for a process.
  3263.     Try re-ordering the overlay description in the ODL file. If the
  3264.     effending overlay is a common library, put it's name after the code
  3265.     body, otherwise the file may need to be copied to one of a
  3266.     different name.
  3267.  
  3268. process requires body
  3269.  
  3270.     at least one process has specified a body name that does not
  3271.     appear in the Task Image as an overlay. An indication of which
  3272.     process is causing the problem can be found from the Console Load
  3273.     Map (qv). Make sure the name specified in the $CREAP macro call
  3274.     is that of one of the object files, check in the task map for
  3275.     the names actually used. If the debugger is included, make sure
  3276.     it, and all other overlays, are separated by commas in the ODL
  3277.     file.
  3278.  
  3279.  
  3280.  
  3281.  
  3282.  
  3283.  
  3284.  
  3285.  
  3286.  
  3287.  
  3288.  
  3289.  
  3290.  
  3291.  
  3292.  
  3293.  
  3294.  
  3295.  
  3296.  
  3297.  
  3298.  
  3299.  
  3300.  
  3301.  
  3302.  
  3303.                                    56
  3304.  
  3305.     3.2.10 Tracing
  3306.  
  3307.      The  loader and it's libraries are liberally scattered with code to
  3308. produce  vast  amounts of output, that describes in detail what is being
  3309. processed.  These  pieces  of  code are normally excluded by surrounding
  3310. them  in  comment  brackets.  The  start  of  a  piece  of trace code is
  3311. indicated  by  {trace  and the end is followed by ecart}. To include the
  3312. trace  statements  change  {trace to {trace} and ecart} to {ecart}. This
  3313. will make it easy to restore them later.
  3314.  
  3315.      The   output  produced  should  be  self  explanatory,  except  for
  3316. PROCEDURE  waiting; which displays the message 'waiting' and waits until
  3317. any  character  is  typed in at the keyboard. All this does is slow down
  3318. the output, since <cntrl-s> and<cntrl-q> are not implemented.
  3319.  
  3320.     3.2.11 Changing The System
  3321.  
  3322.      The   loader   need  not  be  re-compiled  every  time  the  system
  3323. configuration  is changed. This is because the configuration information
  3324. is placed in the root segment of the task image file at link time.
  3325.  
  3326.  
  3327.  
  3328.  
  3329.  
  3330.  
  3331.  
  3332.  
  3333.  
  3334.  
  3335.  
  3336.  
  3337.  
  3338.  
  3339.  
  3340.  
  3341.  
  3342.  
  3343.  
  3344.  
  3345.  
  3346.  
  3347.  
  3348.  
  3349.  
  3350.  
  3351.  
  3352.  
  3353.  
  3354.  
  3355.  
  3356.  
  3357.  
  3358.  
  3359.  
  3360.  
  3361.  
  3362.                                    57
  3363.  
  3364.     3.3    Process Creation
  3365.     ________________________
  3366.  
  3367.      Processes  are  created at compile time by calling the $CREAP macro
  3368. in  the  system  configuration  module.  The  $CREAP  macro  defines the
  3369. attributes  of a process; it's entry point, the name of the overlay that
  3370. contains  it's code body, the devices associated with it and the size of
  3371. the CORAL and System stacks.
  3372.  
  3373.      Note, the name given is the name of the overlay in which the code (
  3374. and therefore the entry point ) is found. This name is that of the first
  3375. module  given  in  the overlay subtree. E.g. If we have a library module
  3376. LIB  and  a  process  body  module  BODY1, then in the ODL file we could
  3377. write:
  3378.  
  3379.     PROCS:    .FCTR    BODY1 - LIB , .........
  3380. in which case the $CREAP call would be
  3381.     $CREAP    $ENTRY , <BODY1> , ............
  3382.  
  3383. or alternatively
  3384.     PROCS    .FCTR    LIB - BODY1 , .........
  3385. in which case the $CREAP call would need to be
  3386.     $CREAP    $ENTRY , <LIB   > , ...........
  3387.  
  3388.      For  this reason all the overlay names must be unique, othewise the
  3389. loader  would not know which code body to give a process. Now suppose we
  3390. have  another  process body module, BODY2, which also uses LIB. We could
  3391. not write:
  3392.  
  3393.     PROCS:    .FCTR    LIB - BODY1 , LIB - BODY2 , .........
  3394. since both overlays would be called LIB. Instead write either
  3395.  
  3396.     PROCS:    .FCTR    BODY1 - LIB , BODY2 - LIB , .........
  3397. with
  3398.     $CREAP    $ENT1 , <BODY1 > , ......
  3399.     $CREAP    $ENT2 , <BODY2 > , ......
  3400.  
  3401. or
  3402.     PROCS:    .FCTR    LIB - BODY1 - BODY2 , ......
  3403. with
  3404.     $CREAP    $ENT1 , <LIB   > , ......
  3405.     $CREAP    $ENT2 , <LIB   > , ......
  3406. or some other combination.
  3407.  
  3408.      Remember  that  the name must be of exactly six characters. Pad out
  3409. with blanks if necessary.
  3410.  
  3411.      The stack sizes are specified using named parameters, these are the
  3412. only  extra  parameters of $CREAP due to the EMMOS extensions. The sizes
  3413. are  given in words, but are automatically rounded up into memory blocks
  3414. (  32  words  ).  A  zero  length R0 stack is acceptable for a non-CORAL
  3415. process,  but the R6 stack should always have some space. If the size is
  3416. not specified it is set to 32 words by default. Note the stack sizes are
  3417. given  seperately  for  each  process,  not  for  each code body, so two
  3418. incarnations  of  the same body could have different stack sizes, though
  3419. it would be a bit odd.
  3420.  
  3421.                                    58
  3422.  
  3423.  
  3424.  
  3425.  
  3426.  
  3427.  
  3428.  
  3429.  
  3430.  
  3431.  
  3432.  
  3433.  
  3434.  
  3435.  
  3436.                 APPENDICES
  3437.                 __________
  3438.  
  3439.  
  3440.  
  3441.  
  3442.  
  3443.  
  3444.  
  3445.  
  3446.  
  3447.  
  3448.  
  3449.  
  3450.  
  3451.  
  3452.  
  3453.  
  3454.  
  3455.  
  3456.  
  3457.  
  3458.  
  3459.  
  3460.  
  3461.  
  3462.  
  3463.  
  3464.  
  3465.  
  3466.  
  3467.  
  3468.  
  3469.  
  3470.  
  3471.  
  3472.  
  3473.  
  3474.  
  3475.  
  3476.  
  3477.  
  3478.  
  3479.  
  3480.                                    59
  3481.  
  3482.     APPENDIX A    Pitfalls.
  3483.  
  3484.  
  3485.  
  3486.  
  3487. A.1 Summary
  3488.  
  3489.      Processes  must  ensure that all communication is performed via the
  3490. global buffer pool.
  3491.  
  3492.      Shared  overlaid  library  procedures must not use the CORAL global
  3493. vector for their entry.
  3494.  
  3495.      CORAL  code  bodies  incarnated  more  than  once should not preset
  3496. variables.
  3497.  
  3498.      All  local  variables  must be taken from the stack, in code bodies
  3499. incarnated more than once.
  3500.  
  3501.      All  IORBs  and  their  data buffers must be located in permanently
  3502. resident memory (ref 2.1.4).
  3503.  
  3504.     A.2.1    Use of local space for inter-process communication
  3505.  
  3506.      Obviously  processes  with  different  code bodies cannot use their
  3507. local  static space ( ie not the stack ) for communication, but at first
  3508. sight it would appear that different incarnations of the same body could
  3509. communicate  using  variables  in the body. Although sometimes possible,
  3510. this  is  extremely  configuration  (  and  even loader ) dependant. The
  3511. problem  arises when there is not enough room to fit all the code body (
  3512. which  includes  local static data ) onto process pages of it's own. The
  3513. loader  may  need  to take a copy of some of the code, which may include
  3514. local  data. In this case there would be more than one copy of the local
  3515. data,  so if two processes use it for communicating, they would actually
  3516. be using two different locations.
  3517.  
  3518.      Therefore,   processes   must  ensure  that  all  communication  is
  3519. performed via the global buffer pool.
  3520.  
  3521.  
  3522.  
  3523.  
  3524.  
  3525.  
  3526.  
  3527.  
  3528.  
  3529.  
  3530.  
  3531.  
  3532.  
  3533.  
  3534.  
  3535.  
  3536.  
  3537.  
  3538.  
  3539.                                    60
  3540.  
  3541. A.2.2 Use of shared, overlaid CORAL libraries.
  3542.  
  3543.      All  CORAL  procedures,  common  variables  etc.,  must  use unique
  3544. indices  to  the global vector, to define themselves ( unless some trick
  3545. is being performed ). This remains true even if the procedure is defined
  3546. in  an  overlay,  because  there is only one global vector. If a library
  3547. module  containing  some  CORAL  procedures only appears in one overlay,
  3548. then  the  global vector will contain the virtual addresses of the entry
  3549. points.  However,  the  procedures will only be in virtual memory when a
  3550. process  which  is  an  incarnation  of that overlay is running, so only
  3551. these processes can use the procedures.
  3552.  
  3553.      This  is  ok,  the problem arises when two or more overlays use the
  3554. library  module. If the overlays are such that when relocated, the entry
  3555. points  of the procedures are at different virtual locations, the global
  3556. vector  mechanism  wont  work. The entry point recorded will probably be
  3557. that  for the last overlay processes by the linker, so the first overlay
  3558. will crash when it tries to call the procedure.
  3559.  
  3560.      To  prevent this all copies of the library module must be relocated
  3561. at  the  same  virtual  locations,  either  by placing it on permanently
  3562. resident EMMOS pages or putting it first in the overlay, though this may
  3563. cause  problems  with the overlay naming convention. A more satisfactory
  3564. solution  in  many  ways,  would be to not use the global vector for the
  3565. procedure  entry.  The  offending procedures would use genuine names for
  3566. their  entry  points,  not  vector indices. This is achieved in CORAL by
  3567. using a large index, outside the bounds of the global vector.
  3568.  
  3569. A.2.3 Use of static variables
  3570.  
  3571.      Any  data  space allocated in a code body, which is incarnated more
  3572. than  once, will be used by more than one incarnation, unless the loader
  3573. causes  a  copy to be made. The processes cannot then use this space for
  3574. private  local  variables,  because  another  may  use the same physical
  3575. memory  for  it's  private  local  variables. Neither can it be used for
  3576. shared  variables, because the loader may have copied them ( see 'use of
  3577. local  space  for inter process communication' ). Constants are ok since
  3578. all  incarnations will require them to remain constant. Beware of string
  3579. constants  though,  although  they  really  should remain constant, some
  3580. unhealthy  procedures actually change some parts of them. Such practices
  3581. should be banned.
  3582.  
  3583.      In  particular,  note  that  the  local variables can be created in
  3584. devious  ways,  in  CORAL  a  preset variable becomes an OWN variable by
  3585. being  allocated  not  on  the  stack,  but  in  the local static space.
  3586. Presetting  and  variables  in  the  outermost block must be avoided for
  3587. multi-incarnate processes.
  3588.  
  3589. Always take local variables from the stack.
  3590.  
  3591.  
  3592.  
  3593.  
  3594.  
  3595.  
  3596.  
  3597.  
  3598.                                    61
  3599.  
  3600.  
  3601.  
  3602.  
  3603.  
  3604.  
  3605.  
  3606.  
  3607.  
  3608.  
  3609.  
  3610.  
  3611.  
  3612.  
  3613.             Don't Panic !
  3614.  
  3615.  
  3616.  
  3617.  
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623.  
  3624.  
  3625.  
  3626.  
  3627.  
  3628.  
  3629.  
  3630.  
  3631.  
  3632.  
  3633.  
  3634.  
  3635.  
  3636.  
  3637.  
  3638.  
  3639.  
  3640.  
  3641.  
  3642.  
  3643.  
  3644.  
  3645.  
  3646.  
  3647.  
  3648.  
  3649.  
  3650.  
  3651.  
  3652.  
  3653.  
  3654.  
  3655.  
  3656.  
  3657.                                    62
  3658.  
  3659.